diff --git a/k8s/local/aztec-sandbox-node/deployment.yaml b/k8s/local/aztec-sandbox-node/deployment.yaml index 10204f8ab..ba1ba570c 100644 --- a/k8s/local/aztec-sandbox-node/deployment.yaml +++ b/k8s/local/aztec-sandbox-node/deployment.yaml @@ -17,7 +17,7 @@ spec: app: aztec-sandbox-node spec: containers: - - image: aztecprotocol/aztec:0.71.0 + - image: aztecprotocol/aztec:0.72.1 name: aztec-sandbox-node resources: limits: diff --git a/packages/backend-utils/package.json b/packages/backend-utils/package.json index ff7cfcb45..7dbe31379 100644 --- a/packages/backend-utils/package.json +++ b/packages/backend-utils/package.json @@ -14,7 +14,7 @@ "lint-base": "yarn run g:lint" }, "dependencies": { - "@aztec/aztec.js": "0.71.0", + "@aztec/aztec.js": "0.72.1", "@chicmoz-pkg/types": "workspace:^", "drizzle-orm": "0.33.0", "exponential-backoff": "3.1.1", diff --git a/packages/backend-utils/src/parse-block.ts b/packages/backend-utils/src/parse-block.ts index 96ae0c2f8..790c2d76b 100644 --- a/packages/backend-utils/src/parse-block.ts +++ b/packages/backend-utils/src/parse-block.ts @@ -6,8 +6,9 @@ const getTxEffectWithHashes = (txEffects: L2Block["body"]["txEffects"]) => { return txEffects.map((txEffect) => { return { ...txEffect, - unencryptedLogslength: txEffect.unencryptedLogsLength.toNumber(), + contractClassLogsLength: txEffect.contractClassLogsLength, privateLogs: txEffect.privateLogs.map((log) => log.toFields()), + publicLogs: txEffect.publicLogs.map((log) => log.toFields()), txHash: txEffect.txHash.toString(), }; }); diff --git a/packages/message-registry/package.json b/packages/message-registry/package.json index 047e4c752..6221cdd5d 100644 --- a/packages/message-registry/package.json +++ b/packages/message-registry/package.json @@ -14,7 +14,7 @@ "lint-base": "yarn run g:lint" }, "dependencies": { - "@aztec/aztec.js": "0.71.0", + "@aztec/aztec.js": "0.72.1", "@chicmoz-pkg/types": "workspace:^" }, "devDependencies": { diff --git a/packages/types/src/aztec/general.ts b/packages/types/src/aztec/general.ts index 74a49b6c6..727594c0c 100644 --- a/packages/types/src/aztec/general.ts +++ b/packages/types/src/aztec/general.ts @@ -1,7 +1,7 @@ import { z } from "zod"; import { l2NetworkIdSchema } from "../network-ids.js"; -export const CHICMOZ_TYPES_AZTEC_VERSION = "0.71.0"; +export const CHICMOZ_TYPES_AZTEC_VERSION = "0.72.1"; export const L1ContractAddressesSchema = z.object({ rollupAddress: z.string(), diff --git a/packages/types/src/aztec/l2Block.ts b/packages/types/src/aztec/l2Block.ts index ddeb32c95..6d90f1e1c 100644 --- a/packages/types/src/aztec/l2Block.ts +++ b/packages/types/src/aztec/l2Block.ts @@ -65,6 +65,7 @@ export const chicmozL2BlockSchema = z.object({ }), }), totalFees: z.coerce.bigint(), + totalManaUsed: z.coerce.bigint(), }), body: z.object({ txEffects: z.array(chicmozL2TxEffectSchema), diff --git a/packages/types/src/aztec/l2TxEffect.ts b/packages/types/src/aztec/l2TxEffect.ts index dd98cf6fa..a97f7c6e9 100644 --- a/packages/types/src/aztec/l2TxEffect.ts +++ b/packages/types/src/aztec/l2TxEffect.ts @@ -2,12 +2,12 @@ import { z } from "zod"; import { aztecAddressSchema, hexStringSchema } from "../general.js"; import { bufferSchema, frNumberSchema, frSchema } from "./utils.js"; -export const unencryptedLogEntrySchema = z.object({ +export const contractClassLogsSchema = z.object({ data: bufferSchema, contractAddress: aztecAddressSchema, }); -const logsSchema = (logEntrySchema: typeof unencryptedLogEntrySchema) => +const logsSchema = (logEntrySchema: typeof contractClassLogsSchema) => z.object({ functionLogs: z.array( z.object({ @@ -16,28 +16,10 @@ const logsSchema = (logEntrySchema: typeof unencryptedLogEntrySchema) => ), }); -//const functionSelectorSchema = z.string().length(10).regex(/^0x[0-9a-fA-F]+$/); - export const chicmozL2PendingTxSchema = z.object({ // TODO: this schema needs to be properly defined, perhaps merged with txEffect hash: hexStringSchema, birthTimestamp: z.number(), - //data: bufferSchema, - //noteEncryptedLogs: logsSchema(noteEncryptedLogEntrySchema), - //encryptedLogs: logsSchema(encryptedLogEntrySchema), - //unencryptedLogs: logsSchema(unencryptedLogEntrySchema), - //contractClassLogs: bufferSchema, - //clientIvcProof: bufferSchema, - //enqueuedPublicFunctionCalls: z.array(bufferSchema), - //publicTeardownFunctionCall: z.object({ - // callContext: z.object({ - // msgSender: aztecAddressSchema, - // contractAddress: aztecAddressSchema, - // functionSelector: functionSelectorSchema, - // isStaticCall: z.boolean(), - // }), - // args: z.array(frSchema), - //}), }); /** @@ -58,12 +40,11 @@ export const chicmozL2TxEffectSchema = z.object({ nullifiers: z.array(frSchema), l2ToL1Msgs: z.array(frSchema), publicDataWrites: z.array(z.object({ leafSlot: frSchema, value: frSchema })), - unencryptedLogsLength: frNumberSchema, privateLogs: z.array(z.array(frSchema)), - unencryptedLogs: logsSchema(unencryptedLogEntrySchema), + publicLogs: z.array(z.array(frSchema)), + contractClassLogs: logsSchema(contractClassLogsSchema), + contractClassLogsLength: frNumberSchema, }); -export type UnencryptedLogEntry = z.infer; - export type ChicmozL2PendingTx = z.infer; export type ChicmozL2TxEffect = z.infer; diff --git a/services/aztec-listener/package.json b/services/aztec-listener/package.json index 80ebfe16c..6d2fe23a6 100644 --- a/services/aztec-listener/package.json +++ b/services/aztec-listener/package.json @@ -4,8 +4,8 @@ "main": "index.js", "license": "Apache-2.0", "dependencies": { - "@aztec/aztec.js": "0.71.0", - "@aztec/circuits.js": "0.71.0", + "@aztec/aztec.js": "0.72.1", + "@aztec/circuits.js": "0.72.1", "@chicmoz-pkg/backend-utils": "workspace:^", "@chicmoz-pkg/logger-server": "workspace:^", "@chicmoz-pkg/message-bus": "workspace:^", diff --git a/services/aztec-listener/src/events/emitted/index.ts b/services/aztec-listener/src/events/emitted/index.ts index 2d0ae1356..b9285bcf8 100644 --- a/services/aztec-listener/src/events/emitted/index.ts +++ b/services/aztec-listener/src/events/emitted/index.ts @@ -39,26 +39,6 @@ export const onPendingTxs = async (txs: Tx[]) => { await publishMessage("PENDING_TXS_EVENT", { txs: txs.map((tx) => { return { - // TODO - //...Tx.schema.parse(tx.toBuffer()), - //data: tx.data.toBuffer(), - //clientIvcProof: tx.clientIvcProof.toBuffer(), - //contractClassLogs: tx.contractClassLogs.toBuffer(), - //unencryptedLogs: tx.unencryptedLogs.toBuffer(), - //encryptedLogs: tx.encryptedLogs.toBuffer(), - //noteEncryptedLogs: tx.noteEncryptedLogs.toBuffer(), - //enqueuedPublicFunctionCalls: tx.enqueuedPublicFunctionCalls.map((call) => - // call.toBuffer() - //), - //publicTeardownFunctionCall: { - // callContext: { - // ...tx.publicTeardownFunctionCall.callContext, - // contractAddress: tx.publicTeardownFunctionCall.callContext.contractAddress.toString(), - // msgSender: tx.publicTeardownFunctionCall.callContext.msgSender.toString(), - // functionSelector: tx.publicTeardownFunctionCall.callContext.functionSelector.toString(), - // }, - // args: tx.publicTeardownFunctionCall.args.map((arg) => arg.toString()), - //}, hash: tx.getTxHash().toString(), birthTimestamp: new Date().getTime(), }; diff --git a/services/ethereum-listener/package.json b/services/ethereum-listener/package.json index cb470ac75..a0928ac99 100644 --- a/services/ethereum-listener/package.json +++ b/services/ethereum-listener/package.json @@ -9,8 +9,8 @@ ], "license": "Apache-2.0", "dependencies": { - "@aztec/aztec.js": "0.71.0", - "@aztec/l1-artifacts": "0.71.0", + "@aztec/aztec.js": "0.72.1", + "@aztec/l1-artifacts": "0.72.1", "@chicmoz-pkg/logger-server": "workspace:^", "@chicmoz-pkg/message-bus": "workspace:^", "@chicmoz-pkg/message-registry": "workspace:^", diff --git a/services/event-cannon/README.md b/services/event-cannon/README.md index 5874a4b74..feb6ecba3 100644 --- a/services/event-cannon/README.md +++ b/services/event-cannon/README.md @@ -1,6 +1,6 @@ # Compile contracts (if changed, or updated version) -aztec-up 0.71.0 +aztec-up 0.72.1 cd contract-projects/YOUR_PROJECT aztec-nargo compile diff --git a/services/event-cannon/package.json b/services/event-cannon/package.json index dcdef3664..e81b22447 100644 --- a/services/event-cannon/package.json +++ b/services/event-cannon/package.json @@ -9,10 +9,10 @@ ], "license": "Apache-2.0", "dependencies": { - "@aztec/accounts": "0.71.0", - "@aztec/aztec.js": "0.71.0", - "@aztec/l1-artifacts": "0.71.0", - "@aztec/noir-contracts.js": "0.71.0", + "@aztec/accounts": "0.72.1", + "@aztec/aztec.js": "0.72.1", + "@aztec/l1-artifacts": "0.72.1", + "@aztec/noir-contracts.js": "0.72.1", "@chicmoz-pkg/logger-server": "workspace:^" }, "devDependencies": { diff --git a/services/event-cannon/src/artifacts/SimpleLogging.ts b/services/event-cannon/src/artifacts/SimpleLogging.ts index 5d065195c..1ae6ed025 100644 --- a/services/event-cannon/src/artifacts/SimpleLogging.ts +++ b/services/event-cannon/src/artifacts/SimpleLogging.ts @@ -32,6 +32,7 @@ import { PublicKeys, type UnencryptedL2Log, type Wallet, + type U128Like, type WrappedFieldLike, } from '@aztec/aztec.js'; import SimpleLoggingContractArtifactJson from '../contract-projects/SimpleLogging/target/simple_logging-SimpleLogging.json' assert { type: 'json' }; @@ -131,9 +132,6 @@ export class SimpleLoggingContract extends ContractBase { /** get_counter_value(counter_id: field) */ get_counter_value: ((counter_id: FieldLike) => ContractFunctionInteraction) & Pick; - /** increase_counter_private(counter_id: field) */ - increase_counter_private: ((counter_id: FieldLike) => ContractFunctionInteraction) & Pick; - /** increase_counter_public(counter_id: field) */ increase_counter_public: ((counter_id: FieldLike) => ContractFunctionInteraction) & Pick; diff --git a/services/event-cannon/src/cannon/scenarios/utils/index.ts b/services/event-cannon/src/cannon/scenarios/utils/index.ts index 29aaf3f0e..db2b469ed 100644 --- a/services/event-cannon/src/cannon/scenarios/utils/index.ts +++ b/services/event-cannon/src/cannon/scenarios/utils/index.ts @@ -61,7 +61,7 @@ export const getNewSchnorrAccount = async ({ salt: Fr; }) => { logger.info(" Creating new Schnorr account..."); - const schnorrAccount = getSchnorrAccount( + const schnorrAccount = await getSchnorrAccount( pxe, secretKey, deriveSigningKey(secretKey), @@ -70,7 +70,7 @@ export const getNewSchnorrAccount = async ({ logger.info( ` Schnorr account created ${schnorrAccount.getAddress().toString()}` ); - const { address } = schnorrAccount.getCompleteAddress(); + const { address } = await schnorrAccount.getCompleteAddress(); logger.info(" Deploying Schnorr account to network..."); await logAndWaitForTx(schnorrAccount.deploy(), "Deploying account"); logger.info(" Getting Schnorr account wallet..."); @@ -208,7 +208,11 @@ export const publicDeployAccounts = async ( ( await registerContractClass(sender, SchnorrAccountContractArtifact) ).request(), - ...instances.map((instance) => deployInstance(sender, instance!).request()), + ...(await Promise.all( + instances.map(async (instance) => + (await deployInstance(sender, instance!)).request() + ) + )), ]); await batch.send().wait(); }; diff --git a/services/event-cannon/src/contract-projects/SimpleLogging/Nargo.toml b/services/event-cannon/src/contract-projects/SimpleLogging/Nargo.toml index eda24b2d9..1443b0403 100644 --- a/services/event-cannon/src/contract-projects/SimpleLogging/Nargo.toml +++ b/services/event-cannon/src/contract-projects/SimpleLogging/Nargo.toml @@ -5,4 +5,4 @@ authors = [ "" ] compiler_version = ">=0.25.0" [dependencies] -aztec = { git = "https://github.com/AztecProtocol/aztec-packages/", tag = "aztec-packages-v0.71.0", directory = "noir-projects/aztec-nr/aztec" } +aztec = { git = "https://github.com/AztecProtocol/aztec-packages/", tag = "aztec-packages-v0.72.1", directory = "noir-projects/aztec-nr/aztec" } diff --git a/services/event-cannon/src/contract-projects/SimpleLogging/src/main.nr b/services/event-cannon/src/contract-projects/SimpleLogging/src/main.nr index 1b458a19d..19b89129c 100644 --- a/services/event-cannon/src/contract-projects/SimpleLogging/src/main.nr +++ b/services/event-cannon/src/contract-projects/SimpleLogging/src/main.nr @@ -4,8 +4,7 @@ use dep::aztec::macros::aztec; contract SimpleLogging { use dep::aztec::prelude::{Map, PublicMutable}; use dep::aztec::{ - //keys::getters::get_public_keys, - macros::{storage::storage, functions::{public, initializer, private, internal}}, + macros::{storage::storage, functions::{public, initializer, internal}}, }; #[storage] struct Storage { @@ -17,17 +16,6 @@ contract SimpleLogging { fn constructor() { } - #[private] - fn increase_counter_private(counter_id: Field) { - //let msg_sender_npk_m_hash = get_public_keys(context.msg_sender()).npk_m.hash(); - //let secret = context.request_nsk_app(msg_sender_npk_m_hash); // get secret key of caller of function - //let nullifier = std::hash::pedersen_hash([context.msg_sender().to_field(), secret]); // derive nullifier from sender and secret - //context.push_nullifier(nullifier); - SimpleLogging::at(context.this_address()).add_to_counter_public(counter_id).enqueue( - &mut context, - ); - } - #[public] #[internal] fn add_to_counter_public(counter_id: Field) { @@ -37,7 +25,7 @@ contract SimpleLogging { #[public] fn increase_counter_public(counter_id: Field) { - context.emit_unencrypted_log(/*message=*/"Counter increased public"); + context.emit_public_log(/*message=*/ "pub log"); SimpleLogging::at(context.this_address()).add_to_counter_public(counter_id); } unconstrained fn get_counter_value(counter_id: Field) -> pub Field { diff --git a/services/event-cannon/src/contract-projects/SimpleLogging/target/simple_logging-SimpleLogging.json b/services/event-cannon/src/contract-projects/SimpleLogging/target/simple_logging-SimpleLogging.json index a74403d75..e66ced111 100644 --- a/services/event-cannon/src/contract-projects/SimpleLogging/target/simple_logging-SimpleLogging.json +++ b/services/event-cannon/src/contract-projects/SimpleLogging/target/simple_logging-SimpleLogging.json @@ -1,10 +1,88 @@ { "transpiled": true, - "noir_version": "1.0.0-beta.1+2d73c1d7bc5b1db7", + "noir_version": "1.0.0-beta.1+4ca7394b2efd7aef", "name": "SimpleLogging", "functions": [ { - "name": "process_log", + "name": "add_to_counter_public", + "is_unconstrained": true, + "custom_attributes": ["public", "internal"], + "abi": { + "error_types": { + "10176877060487216746": { + "error_kind": "string", + "string": "Function add_to_counter_public can only be called internally" + }, + "13699457482007836410": { + "error_kind": "string", + "string": "Not initialized" + }, + "16761564377371454734": { + "error_kind": "string", + "string": "Array index out of bounds" + }, + "17843811134343075018": { + "error_kind": "string", + "string": "Stack too deep" + }, + "206160798890201757": { + "error_kind": "string", + "string": "Storage slot 0 not allowed. Storage slots must start from 1." + }, + "5019202896831570965": { + "error_kind": "string", + "string": "attempt to add with overflow" + } + }, + "parameters": [ + { + "name": "counter_id", + "type": { "kind": "field" }, + "visibility": "private" + } + ], + "return_type": null + }, + "bytecode": "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", + "debug_symbols": "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", + "brillig_names": ["add_to_counter_public"] + }, + { + "name": "constructor", + "is_unconstrained": true, + "custom_attributes": ["public", "initializer"], + "abi": { + "error_types": { + "16761564377371454734": { + "error_kind": "string", + "string": "Array index out of bounds" + }, + "17618083556256589634": { + "error_kind": "string", + "string": "Initialization hash does not match" + }, + "17843811134343075018": { + "error_kind": "string", + "string": "Stack too deep" + }, + "2233873454491509486": { + "error_kind": "string", + "string": "Initializer address is not the contract deployer" + }, + "5019202896831570965": { + "error_kind": "string", + "string": "attempt to add with overflow" + } + }, + "parameters": [], + "return_type": null + }, + "bytecode": "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", + "debug_symbols": "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", + "brillig_names": ["constructor"] + }, + { + "name": "compute_note_hash_and_optionally_a_nullifier", "is_unconstrained": true, "custom_attributes": [], "abi": { @@ -21,97 +99,56 @@ }, "parameters": [ { - "name": "log_plaintext", + "name": "contract_address", "type": { - "fields": [ - { - "name": "storage", - "type": { - "kind": "array", - "length": 18, - "type": { - "kind": "field" - } - } - }, - { - "name": "len", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], + "fields": [{ "name": "inner", "type": { "kind": "field" } }], "kind": "struct", - "path": "std::collections::bounded_vec::BoundedVec" + "path": "aztec::protocol_types::address::aztec_address::AztecAddress" }, "visibility": "private" }, { - "name": "tx_hash", - "type": { - "kind": "field" - }, + "name": "nonce", + "type": { "kind": "field" }, "visibility": "private" }, { - "name": "unique_note_hashes_in_tx", - "type": { - "fields": [ - { - "name": "storage", - "type": { - "kind": "array", - "length": 64, - "type": { - "kind": "field" - } - } - }, - { - "name": "len", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "std::collections::bounded_vec::BoundedVec" - }, + "name": "storage_slot", + "type": { "kind": "field" }, "visibility": "private" }, { - "name": "first_nullifier_in_tx", - "type": { - "kind": "field" - }, + "name": "note_type_id", + "type": { "kind": "field" }, "visibility": "private" }, { - "name": "recipient", + "name": "compute_nullifier", + "type": { "kind": "boolean" }, + "visibility": "private" + }, + { + "name": "serialized_note", "type": { - "fields": [ - { - "name": "inner", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::address::aztec_address::AztecAddress" + "kind": "array", + "length": 0, + "type": { "kind": "field" } }, "visibility": "private" } ], - "return_type": null + "return_type": { + "abi_type": { + "kind": "array", + "length": 4, + "type": { "kind": "field" } + }, + "visibility": "public" + } }, - "bytecode": "H4sIAAAAAAAA/92caVPbMBCGHbABB0LC0fukNy1tHZKQpCctve8L+jlTyJ9oP7j9E7T/tnlBSzZCnaGDNOWtZzxOvMruo7Usr6VVCtH2ttbbC+ZzbI6j5ojz09HgJmWXzTHb31b1qCsLxVggYBwiYBwmYIwJGBMCxhECxlECxjECxpSAsUjAOE7AOEHAWCJgnCRgLBMwVggYpwIwhuCcJuGc8cipY/tQvLPRwW+jhwgYDxMwHiFgPErAeIyA8TgB4wkCxpMEjKcIGE8TMJ4hYDxLwDhHwHiOgPE8AeMFAsaLBIyXCBgvEzBeIWCcJ2C8SsB4jYBxgYDxOgHjDQLGmwSMGQFjlYBxkYCxRsBYJ2BsEDAuETA2CRhbBIxtAsZbBIy3CRjvEDDeJWC8R8B4n4BxmYDxAQHjQwLGFQLGRwSMjwkYnxAwPiVgfEbA+JyA8QUB40sCxlcEjK8JGN8QML4lYHxHwPiegPEDAePHAIwhOD+RcK6ScK4F4ow+W9BDvR0Lt7AwCguPsLAHC2ewMAULP7CwAgsXsDAAifdIbEfieKW3I/EZScVI2EUSLJJMkcSJJEkkISLJD0l0SFJDEhiSrJDEhCShs719rrcjiQRJGkiCQJIBJvExSY5JaEzyYhIVk5SYBMQkGyaxMEmEWmGSA5MIGKTHIDgGmTGIi0FSDEJikA+DaBikwiAQBlkwiCGDBHjJxUskXtLwEoSXDATxCJIRhCLIQxCFIAVBAB6yeIjhIYFOGJ0cOhHcpLgB0LjWoj9v0kh+mGNqjkNK7nERXTW17PrU38randRRP4/8tdToHAuiv9EU/WkY/kwW2q7kff26LmJ32BxX874vV/NBJimzqcpsWmWkPmGud70W1l/VxZLlo0jVRWwXw9iuFSx7+rpomdgvRiHb5vaiZG1PeGz/SN9RkjJ5n6dgyeJ8dz1EliiZXF/YmVfl7LY1ZsmEBZu035LyjWxrRibXNFY6/bXX0Pd3Pft37bVe/R/ba2zJ4nx3Pf62veq2ZbfXJOpv0peKbETJflqyUSX7lfdt1825sP3w9nNX32++n1szDn5tC9to3veBtLthdS5RPtvyjy5vyVIli/NBO0XzPVZ2tC7hSKzyNfO9bI4j6jfy+4rD/ohlf4Dbcc72S+oonzrKo30tmM+Ir9F+vkn5aPe9in3ZfM/2tS21Xf2iP/3Nmqvv88i/IfrHg+iv7+ifCMNfF/2lMP7f0T8Zhr8r+sth9C+J/koY/Q3RPxVE/+JOXKD/XMeOC2bUeY9x7J7jArFftFhDxQUzFo/tHx0XQDbrYK04ZHYfMOuwM+uw49I16VHXlEddxQNax5JHXRWPulKPunxexwmPunz6q+xR15hHXT7bvU9/yXUMOz6VZa44LQqgvxhG/07fL320fhfTdRL7iVX+q+XniSB+7o87SX+mfeGKpXza3uvzWuyXHDzCXXTI9vOHZxuNVrfdarR7IX11abGdFSz9wmqf0+9Eun/R5V3Pflfc59HXmWvMoaz8ii1WsklLliiZMOoxB1dc7JN/L/7X9isOmd0/7/VaTkeDbU3fj+NR/36Oc/91b7a2/8hli9HoT6LBMcXIsp9Y5b+b73Zft997pNvsVLu1TrfT6Kyv1790pi392ofw02+mXHNgmVMAAA==", - "debug_symbols": "tZbLCoMwEEX/ZdZZOFOtrb9SSokaJRCiRC0U8d8bpQ9p13cTuGFyZnXCnak25dTerG+6gYrLTK6r9Gg7H9O8KCqDdc62t/01JevBSbI9GHrt1zyMOoxUHESR8TUVaRKfN9YZKo6yqL/B/D2Y55/BTJarimSGkQVGPsDIKYycwchHGDmHkU8w8hlFZpiDDHOQYQ4yzEGGOcgwBxnmIMMcZJiDDHNQYA4KzEHBOLjEdNfB6tKZV4FoJl/t+sT46M1PtehDV5l6CmYtGd9+sbqcssp4+0FjYEkVyzkuiYue", - "brillig_names": ["process_log"] + "bytecode": "H4sIAAAAAAAA/9VZ227aQBBdsI2xiYHCH0TqWyvZhOsbUi/5DpTAF/QD/NCX9qvLih37MExUJGaisFK0Zmd95uyZ2Ys3HXcq/eNfJzzHoe65y0J9tqEubyuVIlZpybNzJzy7d8IzuhOesSLPjsDT1zTfEneac6k7zcemEV/yAY7gJfc/AHD2N9RZqLtgVwxIlQmD1MJfl/OXzJ0XZf5PWcBMbfAXhN+3wS+J97e6xcexkN8o1M91q+UzvONLEZ4xeQmXbF2wfWe2CGw/mA1z+CezYd4TJ9KtB2NRzKu1dVxobCmMrfNG7VyrHbaR1rkzzdGKYp4xPpw/8SmoT93y6TFbDLaM2RKwkf6+foR+PPYp9PsK7TwnI3eZw2SnmKPWFjkVG+Afy1zSncckrs99ow11j0HPR6aPxV6B+ljo7/WZvsGfnn1Ja9eUiOmJGpFmfezPbBnY4vrcTx5+x+AHsYhHwvp/Cb9Hoe7BO/T+WPDfY/7PeAttqBHHioQ26u/n5OfwPHCn/PlN/d3lOqV3mF7OpTVbD3/V4Gc2/A+En9vgLwl/YIPfnGUeTPBnJeEXNvw3hD+0yZ/mLDmy4b8n/LEJ/nxP++4n15ZmfQjPE2jXW7ur6pozEfrPGVerM9GE8eH64P7rbVOB61iw8RhOBT9TwY+ElSliPShijT7oGPuKWANFrKEilmYcU0UsTb1yRaxCEUsz7zX1ojhK5zRftqEubyzSOU0Rv5LOaZrf7qQ15VcsaIjjS1j/X0zngQnPakZ7Ds118oG+CyPf1+7X5L8Q+BDvXLDdchm7X6wPm/ViczySVcvZpolnwbjyNvwmwvUY+0t7v3TuU9S6lL77h6CrLzHYCmZLwEYcpe/+oRH/a/RH/2PBxvf/a2M5cZf74YCNG++4tipjbu//pLt54/Vrce3cJP+5u1yv3+t+EfXhZ+lc4DoWbPx8kgt+csHPPWLxO3rU0Oc16RTXrV0rlqt1+48tWosSd37v75j/hPX/E37j2Ki+Zc0/rHbV4Wl32C12r6/zl92E4fvSBZ3+Ab+1O0oNHwAA", + "debug_symbols": "tdfRioQgFAbgd/HaC49aZq+yLIOVDYJYWC0s0buvDbO7w8zl8N8EJ06fIf7I2dngu+16CWmcFtZ+7CxOvVvDlEq1H5x1OcQYrpfH10ycD6tu/cvs0lkuq8sra5XkzKeBtVqUr8cQPWtrefCXRvPbaMxfYyWPT86sRsEVCq5RsEHBDQq2IJiEgMkEkyVMVjBZw+QKJtcw2cDkBibDMkiwDBIsgwTLIMEySLAMEiyD9F4Grbo3lm19oQ2ObnC0hdFS4GjC0RJHKxytcXSFo3FplLg0SlwaJSiNR6m+XA6ui/4+M41b6h9GqPV79k/T1Jyn3g9b9udc9T9SnYdYaa717RYvBZX/I2XKImWhHw==", + "brillig_names": ["compute_note_hash_and_optionally_a_nullifier"] }, { "name": "public_dispatch", @@ -160,16 +197,14 @@ "parameters": [ { "name": "selector", - "type": { - "kind": "field" - }, + "type": { "kind": "field" }, "visibility": "private" } ], "return_type": null }, - "bytecode": "JgACBAEnAAABBIBEJgAABAMmAgIEASYCAwQAHxgAAwACgEMtCIBDAAEkAAAAQCcCAAEEgEQmAgIEADoNAAEAAiQAAAdpKAIAAgAX8SiICjgBAgMmAgQEACYCBgQDADgEBgUsCAECABABBQEmAwIEAQAoAgIFLA4EBQAoBQIFLA4EBSYCBQQDADgCBQQmAgQEACMCAAMAAACeIgAAAOAmAgMEBSwIAAUAEAADACQAAAeSLAQAACwNAgMAKAMCAywOAwIAKAICBiwNBgUmAgcEAgA4BgcDOg0AAwAFIgAAAOAoAgADAJI5JNYKOAEDBSYCAwEAJgIGAAYmAgcEASYCCAAAIwIABQAAAQ8iAAACnywIAQUmAgkEAgAQAQkBJgMFBAEAKAUCCR88AAcABwAJLA0FCQAoCQIJLA4JBSwIAQkAAAECASwOBQksCAEFAAABAgEsDgQFJgILBAwsCAAMLAwJDSwMBQ4sDAYPABAACwAkAAAKgCwEAAAsDA0KLAgBBQAAAQIBLA4DBSwIAQkAAAECASwOCAksCAELAAABAgEmAgwAKiwODAsmAgwEDSwIAA0sDAUOLAwJDywMCxAAEAAMACQAAArbLAQAAB4CAAwBHgIADQAKOAwNDiMCAA4AAAHoJAAACwUmAgwAASYCDQAZJgISBBMsCAATLAwFFCwMCRUsDAsWLAwMFywMDRgsDAoZABAAEgAkAAALFywEAAAsDBQOLAwVDywMFhAsDBcRLgwAEQASADgSDBEmAhYEFywIABcsDAUYLAwJGSwMCxosDAwbLAwNHCwMCh0AEAAWACQAAAsXLAQAACwMGBIsDBkTLAwaFCwMGxUvDAARABUAKAICCiwNCgkmAgsEAgA4CgsFOg0ABQAJIgAAAp8oAgAFAK/cIDsKOAEFCSYCAQJzJgIFAmUmAgoCbCYCCwJjJgIMAnImAg0CbiYCDgIgJgIPAnQmAhACbyMCAAkAAALnIgAABcIsCAERJgISBAIAEAESASYDEQQBACgRAhIfPAAHAAcAEiwNERIAKBICEiwOEhEsCAESAAABAgEsDhESLAgBEQAAAQIBLA4EESYCFAQVLAgAFSwMEhYsDBEXLAwGGAAQABQAJAAACoAsBAAALAwWEywIAQYAAAECASwOAwYsCAERAAABAgEsDggRLAgBEgAAAQIBJgIUAAssDhQSJgIUBBUsCAAVLAwGFiwMERcsDBIYABAAFAAkAAAK2ywEAAAmAgYCYiYCEQJpJgISAnUmAhQCZCYCFQJDJgIWAnAmAhcCYSwIARgmAhkEGQAQARkBJgMYBAEAKBgCGSwMGRosDhUaACgaAhosDhAaACgaAhosDhIaACgaAhosDg0aACgaAhosDg8aACgaAhosDgUaACgaAhosDgwaACgaAhosDg4aACgaAhosDhEaACgaAhosDg0aACgaAhosDgsaACgaAhosDgwaACgaAhosDgUaACgaAhosDhcaACgaAhosDgEaACgaAhosDgUaACgaAhosDhQaACgaAhosDg4aACgaAhosDhYaACgaAhosDhIaACgaAhosDgYaACgaAhosDgoaACgaAhosDhEaACgaAhosDgsaLAgBBiYCEQQZABABEQEmAwYEAQAoBgIRJgISBBgAOBIREiwMERQMOBQSFRYMFRUjAgAVAAAE+ywOCBQAKBQCFCIAAATcLAgBCAAAAQIBLA4GCCYCBgQYLAwECSIAAAUWDDgJBhEjAgARAAAG7CIAAAUoLA0IByYCEQQYBigRAggmAhMEAwA4ERMSLAgBCQAQARIBJgMJBAEAKAkCEiwOERIAKBICEiwOERImAhMEAwA4CRMSACgHAhMtBAATgAMtBAASgAQtBAARgAUkAAAMvgAoCQISLA0SESYCEwQCADgSEwc2DQAHABEeAgAGAAAoAgIRLA0RCSYCEgQCADgREgc6DQAHAAkiAAAFwiYCAgJVJgIGAmsmAgcCdywIAQgmAgkEEQAQAQkBJgMIBAEAKAgCCSwMCREsDgIRACgRAhEsDg0RACgRAhEsDgYRACgRAhEsDg0RACgRAhEsDhARACgRAhEsDgcRACgRAhEsDg0RACgRAhEsDg4RACgRAhEsDgERACgRAhEsDgURACgRAhEsDgoRACgRAhEsDgURACgRAhEsDgsRACgRAhEsDg8RACgRAhEsDhARACgRAhEsDgwRJgIBAQEKOAMBAiMCAAIAAAbrJgIFBBIsCAEGJgIHBBIAEAEHASwMBgcpAwAHBeWPmFkHMWKQACgHAgcAKAgCCSYCCgQQLQQACYADLQQAB4AELQQACoAFJAAADL4mAgkEEAA4BwkHLA4EBwAoBwIHOw0GBSUsDQgRJgITBBgMOAkTFCMCABQAAAcHJAAADQQA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", - "debug_symbols": "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", + "bytecode": "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", + "debug_symbols": "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", "brillig_names": ["public_dispatch"] }, { @@ -190,40 +225,6 @@ "debug_symbols": "nZLLCoMwEEX/ZdYuMvHV5lekSNQogZBIjIUi/nujSGuLm2QzcId77uos0IlmHmqpezMBqxZQpuVOGu3TsibQWKmUHOrzG8h2EPf+NHK9xclx64ClNAGhO2AZ8XQvlQBW0PWRANLAfhrYzwL7eVifXu4jIbfyQJAgZh8K03zH8jisiMPKOOwWhaV4jWFZfLF7/outPj65lbxR4pCsn3V7cs69RvGn32hNK7rZik3Ek4P+VlgmlPpZP/0G", "brillig_names": ["sync_notes"] }, - { - "name": "constructor", - "is_unconstrained": true, - "custom_attributes": ["public", "initializer"], - "abi": { - "error_types": { - "16761564377371454734": { - "error_kind": "string", - "string": "Array index out of bounds" - }, - "17618083556256589634": { - "error_kind": "string", - "string": "Initialization hash does not match" - }, - "17843811134343075018": { - "error_kind": "string", - "string": "Stack too deep" - }, - "2233873454491509486": { - "error_kind": "string", - "string": "Initializer address is not the contract deployer" - }, - "5019202896831570965": { - "error_kind": "string", - "string": "attempt to add with overflow" - } - }, - "parameters": [], - "return_type": null - }, - "bytecode": "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", - "debug_symbols": "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", - "brillig_names": ["constructor"] - }, { "name": "increase_counter_public", "is_unconstrained": true, @@ -246,1682 +247,16 @@ "parameters": [ { "name": "counter_id", - "type": { - "kind": "field" - }, + "type": { "kind": "field" }, "visibility": "private" } ], "return_type": null }, - "bytecode": "JgACBAEnAAABBIBEJgAABAMmAgIEASYCAwQAHxgAAwACgEMtCIBDAAEkAAAAQCcCAAEEgEQmAgIEADoNAAEAAiQAAANULAgBAwAAAQIBJgIEAQAsDgQDLAgBAwAAAQIBJgIEAAAsDgQDLAgBAwAAAQIBJgIFAAIsDgUDHgIAAwAeAgAFADI4AAMABQAGJgIDAQEjAgAGAAAAnyQAAAN9JgIDAnAmAgUCYSYCBgIgJgIHAnQmAggCbyYCCQJsJgIKAmQmAgsCYyYCDAJyJgINAm4mAg4CQyYCDwJiJgIQAnMmAhECaSYCEgJlJgITAnUsCAEUJgIVBBkAEAEVASYDFAQBACgUAhUsDBUWLA4OFgAoFgIWLA4IFgAoFgIWLA4TFgAoFgIWLA4NFgAoFgIWLA4HFgAoFgIWLA4SFgAoFgIWLA4MFgAoFgIWLA4GFgAoFgIWLA4RFgAoFgIWLA4NFgAoFgIWLA4LFgAoFgIWLA4MFgAoFgIWLA4SFgAoFgIWLA4FFgAoFgIWLA4QFgAoFgIWLA4SFgAoFgIWLA4KFgAoFgIWLA4GFgAoFgIWLA4DFgAoFgIWLA4TFgAoFgIWLA4PFgAoFgIWLA4JFgAoFgIWLA4RFgAoFgIWLA4LFiwIAQMmAgUEGQAQAQUBJgMDBAEAKAMCBSYCBgQYADgGBQYsDAUHDDgHBggWDAgIIwIACAAAAiMsDgQHACgHAgciAAACBCwIAQQAAAECASwOAwQmAgMEASYCBQQYJgIGBAAsDAYCIgAAAkgMOAIFASMCAAEAAALXIgAAAlosDQQBJgIEBBgGKAQCAiYCBwQDADgEBwYsCAEDABABBgEmAwMEAQAoAwIGLA4EBgAoBgIGLA4EBiYCBwQDADgDBwYAKAECBy0EAAeAAy0EAAaABC0EAASABSQAAAOPACgDAgYsDQYEJgIHBAIAOAYHATYNAAEABB4CAAEAJSwNBAEmAgcEGAw4AgcIIwIACAAAAvIkAAAD1QAoFAIHADgHAggsDQgGHAwGBwAmAggEGAw4AggJIwIACQAAAxwkAAAD1S0EAAGAAycAgAQEABkkAAAD5y0IgAUABgAoBgIIADgIAgksDgcJADgCAwEsDgYELAwBAiIAAAJIJwCABAR4AA0AAACABIADIwCAAwAAA3wpAQABBfeh86+lrdTKOwEBAiUpAQABBb4eP/8+pPb6OwEBAiUBAIADgAWABy0AgAOACC0AgASACQsAgAiAB4AKIwCACgAAA9QtAYAIgAYtAoAGgAkBAIAIAAKACAEAgAkAAoAJIgAAA6MlKQEAAQXonQn+oREtDjsBAQIlLQGAA4AGCwCABgACgAcjAIAHAAAEAiIAAAQNLQCAA4AFIgAABHQtAAABgAUBAAABgAQAAQEAgAOABIAJLQCAA4AKLQCABYALCwCACoAJgAwjAIAMAAAEYC0BgAqACC0CgAiACwEAgAoAAoAKAQCACwACgAsiAAAELycBgAUEAAEDAIAGAAKABiIAAAR0JS0AGMoYyg==", - "debug_symbols": "zZvdTiMxDIXfZa7nIo4dJ+ZVVitUoKBKVYtKWWmFePed6TKlamlRD5PWN6gDPvGH7fx4IG/Nw/Tu9el2tnhcvjQ3v96a+fJ+sp4tF93T23vb3K1m8/ns6Xb3203ov6ht7F+eJ4v+8WU9Wa2bG1ILbTNdPHQfcwjdCI+z+bS50fj+u20yA5pyvqYAfko+X2MEaPR8DQVCRAkRAWklEkSEeIrnZrY9NA4hDcYhpq2x2RfGIjqM3H20rXGmL4wLc/wwLixl13jDXkZgL4MH6uAvx85jxF1oG3f9Ju6UsgzGyuE0uwmVD2MTpX12oVHZu3m1y77xoLU9JKnuAZmOikx8ZOegjHjKiKeCeCqIJ0M8GeApBkFEiCdkK4jIVhAj4ikinhjxxIgnYUQEnJBiQjwlxJMinhQ4jcVMiAg4j8USEFFCREgZIQtLNCC5HBgRAclliogISC5HQkRAcpkDIhJEBJQRI6sRI6sRJyS5CSkjRZKrSBllJLkZKSPkmMPIMYcLklxDysiA5EqIiAhIrhAhIiC5EgMiEkQElJEwIyKgjESQ5ApSRglJbkLKSJHkKlJGSNMlSNMlR17YdWv8IOLyTatayuDAdhrVL3t/Zhq62u7j5xuRaP9pSnRFkz3RmKvYmKfYpOApNim4ig25is2RM/6VaI40D9eiSZ5ojpwVrkXjak6JqzklrmKTXM2p5Gq9OdLGVaPhsqUR26fRS++aKluazIc0o2aKZJemH5+o8viV+WNl/liZ/8jrs/HGT3XHl8r8Upvf6o6fpPL4pe74ypXHr8yfK/PnyvVTKte/VV4/bYT1M9l2/Hx6NzWlPNhq4j2YHMgTTHIEQ8ETjKfIHDlgiOgAI6qnYUb8J6Ycs6OzcuYLdzVZtzRFDmnUE424is2455yf0ox7KvoxjavYqKvYaLkajR10wzlf+O3byd48X/qvRKdpiqvYGLmiUUc0xdUbphLMEw2JJ5oYXNEkTzTsKjbsqm7Yz5x67x7/TFazyd18+nEh6vF1cb9zP2r993m6d1XqebW8nz68rqb9panP+1J9xslyG6l0v2W/31Dhlox/97du+scsLWXrH2nz09BSiR1Dx/EP", + "bytecode": "JgACBAEnAAABBIBEJgAABAMmAgIEASYCAwQAHxgAAwACgEMtCIBDAAEkAAAAQCcCAAEEgEQmAgIEADoNAAEAAiQAAAKfLAgBAwAAAQIBJgIEAQAsDgQDLAgBAwAAAQIBJgIEAAAsDgQDLAgBAwAAAQIBJgIFAAIsDgUDHgIAAwAeAgAFADI4AAMABQAGJgIDAQEjAgAGAAAAnyQAAALIJgIDAnAmAgUCICYCBgJsJgIHAnUmAggCbyYCCQJiJgIKAmcsCAELJgIMBAgAEAEMASYDCwQBACgLAgwsDAwNLA4DDQAoDQINLA4HDQAoDQINLA4JDQAoDQINLA4FDQAoDQINLA4GDQAoDQINLA4IDQAoDQINLA4KDSwIAQMmAgUECAAQAQUBJgMDBAEAKAMCBSwMBQYsDgQGACgGAgYsDgQGACgGAgYsDgQGACgGAgYsDgQGACgGAgYsDgQGACgGAgYsDgQGACgGAgYsDgQGLAgBBAAAAQIBLA4DBCYCAwQAJgIFBAcmAgYEASwMAwIiAAABkww4AgUBIwIAAQAAAiIiAAABpSwNBAEmAgQEBwYoBAICJgIHBAMAOAQHBiwIAQMAEAEGASYDAwQBACgDAgYsDgQGACgGAgYsDgQGJgIHBAMAOAMHBgAoAQIHLQQAB4ADLQQABoAELQQABIAFJAAAAtoAKAMCBiwNBgQmAgcEAgA4BgcBNg0AAQAEHgIAAQAlLA0EASYCBwQHDDgCBwgjAgAIAAACPSQAAAMgACgLAgcAOAcCCCwNCAMcDAMHACYCCAQHDDgCCAkjAgAJAAACZyQAAAMgLQQAAYADJwCABAQACCQAAAMyLQiABQADACgDAggAOAgCCSwOBwkAOAIGASwOAwQsDAECIgAAAZMnAIAEBHgADQAAAIAEgAMjAIADAAACxykBAAEF96Hzr6Wt1Mo7AQECJSkBAAEFvh4//z6k9vo7AQECJQEAgAOABYAHLQCAA4AILQCABIAJCwCACIAHgAojAIAKAAADHy0BgAiABi0CgAaACQEAgAgAAoAIAQCACQACgAkiAAAC7iUpAQABBeidCf6hES0OOwEBAiUtAYADgAYLAIAGAAKAByMAgAcAAANNIgAAA1gtAIADgAUiAAADvy0AAAGABQEAAAGABAABAQCAA4AEgAktAIADgAotAIAFgAsLAIAKgAmADCMAgAwAAAOrLQGACoAILQKACIALAQCACgACgAoBAIALAAKACyIAAAN6JwGABQQAAQMAgAYAAoAGIgAAA78lLQAYyhjK", + "debug_symbols": "zZrbjuIwDED/pc99iBPbiedXVqMRlzJCQoC4rLRC/Pu27LSLoMsIb1P8MpqALwc7sdM0p2JeTY+fH8v1YrMv3n6citVmNjksN+t6dDqXxXS3XK2Wnx/XHxeu+cNykd9vJ+tmuD9MdofiDVhcWVTref1vdK62sFiuquKN/fm9LGJQ6KTndZLCT4rP6wgodPh5HXCgUSKNkiKtAKhR0njyz2a2vBd2jlph56kTFukRRsT4JYxI3AlH6BFOobOcgodr4Qt7GoA9+Va4hh+PPQwRd4Qu7vxN3IG4E2aIj9klSCssGPCWHWFQ9npdXbNfPHBuD4TZPWiWI2sWvqZzQNR4ihpPSeMpaTyJxpMo+qF3QaOk8QQaT6Dx5L1GSdF9fQCNkqL7enQaJdQoKSasJ01ySZNc1iSXFVs4HzXJjZpplHqTG6Ht6DHQ4wqeuO3nSfzjloiJUtv7E0kn7CX8YUFDLGKHRQzFRezEJTg7cQn9fek1LOANsUQ7LB4MsbAdlmCnB4T+HcqLWAzVOjRU69BQrevf/b2IxVCtY0M9gA3Vumio1kU7tQ7dqOsoUccifMcyap8WaA+gULy7ZxkuR+JuTzBxwM7bZz0rO2Zlx7zsktM6YVbrWdk5KzunnNZjyGo95rSefFbrWdklK7vknDPkcs53ApfV+n/XSOpeUTl83CeFup4tDHyL4p0dFLSDImZQgp2o/GPjkLDds13Z70UZ8B0y4ajPJg/3vURjPpuID92+N8A9C9lhYUNx4WSHJQZDLIbikgzFJcUXseDdsyzJmGdCj5+rSaIZFnZ24sLgDLGQHRZDZ0Lskx2WEAyxiB2WUd+XfMdiKC5kaL6QlXV0roc/J7vlZLqqvu6YL47r2dWV88OvbXVz+3y728yq+XFXNffQ/15Bb+o3kJSQXP0bm2gDUglE781F5mYYuASEZgiXb309xJqh5vgN", "brillig_names": ["increase_counter_public"] }, - { - "name": "increase_counter_private", - "is_unconstrained": false, - "custom_attributes": ["private"], - "abi": { - "error_types": { - "17843811134343075018": { - "error_kind": "string", - "string": "Stack too deep" - }, - "5019202896831570965": { - "error_kind": "string", - "string": "attempt to add with overflow" - } - }, - "parameters": [ - { - "name": "inputs", - "type": { - "fields": [ - { - "name": "call_context", - "type": { - "fields": [ - { - "name": "msg_sender", - "type": { - "fields": [ - { - "name": "inner", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::address::aztec_address::AztecAddress" - } - }, - { - "name": "contract_address", - "type": { - "fields": [ - { - "name": "inner", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::address::aztec_address::AztecAddress" - } - }, - { - "name": "function_selector", - "type": { - "fields": [ - { - "name": "inner", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::function_selector::FunctionSelector" - } - }, - { - "name": "is_static_call", - "type": { - "kind": "boolean" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::call_context::CallContext" - } - }, - { - "name": "historical_header", - "type": { - "fields": [ - { - "name": "last_archive", - "type": { - "fields": [ - { - "name": "root", - "type": { - "kind": "field" - } - }, - { - "name": "next_available_leaf_index", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot" - } - }, - { - "name": "content_commitment", - "type": { - "fields": [ - { - "name": "num_txs", - "type": { - "kind": "field" - } - }, - { - "name": "blobs_hash", - "type": { - "kind": "field" - } - }, - { - "name": "in_hash", - "type": { - "kind": "field" - } - }, - { - "name": "out_hash", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::content_commitment::ContentCommitment" - } - }, - { - "name": "state", - "type": { - "fields": [ - { - "name": "l1_to_l2_message_tree", - "type": { - "fields": [ - { - "name": "root", - "type": { - "kind": "field" - } - }, - { - "name": "next_available_leaf_index", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot" - } - }, - { - "name": "partial", - "type": { - "fields": [ - { - "name": "note_hash_tree", - "type": { - "fields": [ - { - "name": "root", - "type": { - "kind": "field" - } - }, - { - "name": "next_available_leaf_index", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot" - } - }, - { - "name": "nullifier_tree", - "type": { - "fields": [ - { - "name": "root", - "type": { - "kind": "field" - } - }, - { - "name": "next_available_leaf_index", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot" - } - }, - { - "name": "public_data_tree", - "type": { - "fields": [ - { - "name": "root", - "type": { - "kind": "field" - } - }, - { - "name": "next_available_leaf_index", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::partial_state_reference::PartialStateReference" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::state_reference::StateReference" - } - }, - { - "name": "global_variables", - "type": { - "fields": [ - { - "name": "chain_id", - "type": { - "kind": "field" - } - }, - { - "name": "version", - "type": { - "kind": "field" - } - }, - { - "name": "block_number", - "type": { - "kind": "field" - } - }, - { - "name": "slot_number", - "type": { - "kind": "field" - } - }, - { - "name": "timestamp", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 64 - } - }, - { - "name": "coinbase", - "type": { - "fields": [ - { - "name": "inner", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::address::eth_address::EthAddress" - } - }, - { - "name": "fee_recipient", - "type": { - "fields": [ - { - "name": "inner", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::address::aztec_address::AztecAddress" - } - }, - { - "name": "gas_fees", - "type": { - "fields": [ - { - "name": "fee_per_da_gas", - "type": { - "kind": "field" - } - }, - { - "name": "fee_per_l2_gas", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::gas_fees::GasFees" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::global_variables::GlobalVariables" - } - }, - { - "name": "total_fees", - "type": { - "kind": "field" - } - }, - { - "name": "total_mana_used", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::block_header::BlockHeader" - } - }, - { - "name": "tx_context", - "type": { - "fields": [ - { - "name": "chain_id", - "type": { - "kind": "field" - } - }, - { - "name": "version", - "type": { - "kind": "field" - } - }, - { - "name": "gas_settings", - "type": { - "fields": [ - { - "name": "gas_limits", - "type": { - "fields": [ - { - "name": "da_gas", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - }, - { - "name": "l2_gas", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::gas::Gas" - } - }, - { - "name": "teardown_gas_limits", - "type": { - "fields": [ - { - "name": "da_gas", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - }, - { - "name": "l2_gas", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::gas::Gas" - } - }, - { - "name": "max_fees_per_gas", - "type": { - "fields": [ - { - "name": "fee_per_da_gas", - "type": { - "kind": "field" - } - }, - { - "name": "fee_per_l2_gas", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::gas_fees::GasFees" - } - }, - { - "name": "max_priority_fees_per_gas", - "type": { - "fields": [ - { - "name": "fee_per_da_gas", - "type": { - "kind": "field" - } - }, - { - "name": "fee_per_l2_gas", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::gas_fees::GasFees" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::gas_settings::GasSettings" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::transaction::tx_context::TxContext" - } - }, - { - "name": "start_side_effect_counter", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::context::inputs::private_context_inputs::PrivateContextInputs" - }, - "visibility": "private" - }, - { - "name": "counter_id", - "type": { - "kind": "field" - }, - "visibility": "private" - } - ], - "return_type": { - "abi_type": { - "fields": [ - { - "name": "call_context", - "type": { - "fields": [ - { - "name": "msg_sender", - "type": { - "fields": [ - { - "name": "inner", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::address::aztec_address::AztecAddress" - } - }, - { - "name": "contract_address", - "type": { - "fields": [ - { - "name": "inner", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::address::aztec_address::AztecAddress" - } - }, - { - "name": "function_selector", - "type": { - "fields": [ - { - "name": "inner", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::function_selector::FunctionSelector" - } - }, - { - "name": "is_static_call", - "type": { - "kind": "boolean" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::call_context::CallContext" - } - }, - { - "name": "args_hash", - "type": { - "kind": "field" - } - }, - { - "name": "returns_hash", - "type": { - "kind": "field" - } - }, - { - "name": "min_revertible_side_effect_counter", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - }, - { - "name": "is_fee_payer", - "type": { - "kind": "boolean" - } - }, - { - "name": "max_block_number", - "type": { - "fields": [ - { - "name": "_opt", - "type": { - "fields": [ - { - "name": "_is_some", - "type": { - "kind": "boolean" - } - }, - { - "name": "_value", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "std::option::Option" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::max_block_number::MaxBlockNumber" - } - }, - { - "name": "note_hash_read_requests", - "type": { - "kind": "array", - "length": 16, - "type": { - "fields": [ - { - "name": "value", - "type": { - "kind": "field" - } - }, - { - "name": "counter", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::read_request::ReadRequest" - } - } - }, - { - "name": "nullifier_read_requests", - "type": { - "kind": "array", - "length": 16, - "type": { - "fields": [ - { - "name": "value", - "type": { - "kind": "field" - } - }, - { - "name": "counter", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::read_request::ReadRequest" - } - } - }, - { - "name": "key_validation_requests_and_generators", - "type": { - "kind": "array", - "length": 16, - "type": { - "fields": [ - { - "name": "request", - "type": { - "fields": [ - { - "name": "pk_m", - "type": { - "fields": [ - { - "name": "x", - "type": { - "kind": "field" - } - }, - { - "name": "y", - "type": { - "kind": "field" - } - }, - { - "name": "is_infinite", - "type": { - "kind": "boolean" - } - } - ], - "kind": "struct", - "path": "std::embedded_curve_ops::EmbeddedCurvePoint" - } - }, - { - "name": "sk_app", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::validation_requests::key_validation_request::KeyValidationRequest" - } - }, - { - "name": "sk_app_generator", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::validation_requests::key_validation_request_and_generator::KeyValidationRequestAndGenerator" - } - } - }, - { - "name": "note_hashes", - "type": { - "kind": "array", - "length": 16, - "type": { - "fields": [ - { - "name": "value", - "type": { - "kind": "field" - } - }, - { - "name": "counter", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::note_hash::NoteHash" - } - } - }, - { - "name": "nullifiers", - "type": { - "kind": "array", - "length": 16, - "type": { - "fields": [ - { - "name": "value", - "type": { - "kind": "field" - } - }, - { - "name": "counter", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - }, - { - "name": "note_hash", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::nullifier::Nullifier" - } - } - }, - { - "name": "private_call_requests", - "type": { - "kind": "array", - "length": 5, - "type": { - "fields": [ - { - "name": "call_context", - "type": { - "fields": [ - { - "name": "msg_sender", - "type": { - "fields": [ - { - "name": "inner", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::address::aztec_address::AztecAddress" - } - }, - { - "name": "contract_address", - "type": { - "fields": [ - { - "name": "inner", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::address::aztec_address::AztecAddress" - } - }, - { - "name": "function_selector", - "type": { - "fields": [ - { - "name": "inner", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::function_selector::FunctionSelector" - } - }, - { - "name": "is_static_call", - "type": { - "kind": "boolean" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::call_context::CallContext" - } - }, - { - "name": "args_hash", - "type": { - "kind": "field" - } - }, - { - "name": "returns_hash", - "type": { - "kind": "field" - } - }, - { - "name": "start_side_effect_counter", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - }, - { - "name": "end_side_effect_counter", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::private_call_request::PrivateCallRequest" - } - } - }, - { - "name": "public_call_requests", - "type": { - "kind": "array", - "length": 16, - "type": { - "fields": [ - { - "name": "inner", - "type": { - "fields": [ - { - "name": "msg_sender", - "type": { - "fields": [ - { - "name": "inner", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::address::aztec_address::AztecAddress" - } - }, - { - "name": "contract_address", - "type": { - "fields": [ - { - "name": "inner", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::address::aztec_address::AztecAddress" - } - }, - { - "name": "function_selector", - "type": { - "fields": [ - { - "name": "inner", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::function_selector::FunctionSelector" - } - }, - { - "name": "is_static_call", - "type": { - "kind": "boolean" - } - }, - { - "name": "args_hash", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::public_call_request::PublicCallRequest" - } - }, - { - "name": "counter", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::side_effect::counted::Counted" - } - } - }, - { - "name": "public_teardown_call_request", - "type": { - "fields": [ - { - "name": "msg_sender", - "type": { - "fields": [ - { - "name": "inner", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::address::aztec_address::AztecAddress" - } - }, - { - "name": "contract_address", - "type": { - "fields": [ - { - "name": "inner", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::address::aztec_address::AztecAddress" - } - }, - { - "name": "function_selector", - "type": { - "fields": [ - { - "name": "inner", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::function_selector::FunctionSelector" - } - }, - { - "name": "is_static_call", - "type": { - "kind": "boolean" - } - }, - { - "name": "args_hash", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::public_call_request::PublicCallRequest" - } - }, - { - "name": "l2_to_l1_msgs", - "type": { - "kind": "array", - "length": 2, - "type": { - "fields": [ - { - "name": "recipient", - "type": { - "fields": [ - { - "name": "inner", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::address::eth_address::EthAddress" - } - }, - { - "name": "content", - "type": { - "kind": "field" - } - }, - { - "name": "counter", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::messaging::l2_to_l1_message::L2ToL1Message" - } - } - }, - { - "name": "private_logs", - "type": { - "kind": "array", - "length": 16, - "type": { - "fields": [ - { - "name": "log", - "type": { - "fields": [ - { - "name": "fields", - "type": { - "kind": "array", - "length": 18, - "type": { - "kind": "field" - } - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::log::Log" - } - }, - { - "name": "note_hash_counter", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - }, - { - "name": "counter", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::private_log::PrivateLogData" - } - } - }, - { - "name": "contract_class_logs_hashes", - "type": { - "kind": "array", - "length": 1, - "type": { - "fields": [ - { - "name": "value", - "type": { - "kind": "field" - } - }, - { - "name": "counter", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - }, - { - "name": "length", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::log_hash::LogHash" - } - } - }, - { - "name": "start_side_effect_counter", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - }, - { - "name": "end_side_effect_counter", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - }, - { - "name": "historical_header", - "type": { - "fields": [ - { - "name": "last_archive", - "type": { - "fields": [ - { - "name": "root", - "type": { - "kind": "field" - } - }, - { - "name": "next_available_leaf_index", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot" - } - }, - { - "name": "content_commitment", - "type": { - "fields": [ - { - "name": "num_txs", - "type": { - "kind": "field" - } - }, - { - "name": "blobs_hash", - "type": { - "kind": "field" - } - }, - { - "name": "in_hash", - "type": { - "kind": "field" - } - }, - { - "name": "out_hash", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::content_commitment::ContentCommitment" - } - }, - { - "name": "state", - "type": { - "fields": [ - { - "name": "l1_to_l2_message_tree", - "type": { - "fields": [ - { - "name": "root", - "type": { - "kind": "field" - } - }, - { - "name": "next_available_leaf_index", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot" - } - }, - { - "name": "partial", - "type": { - "fields": [ - { - "name": "note_hash_tree", - "type": { - "fields": [ - { - "name": "root", - "type": { - "kind": "field" - } - }, - { - "name": "next_available_leaf_index", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot" - } - }, - { - "name": "nullifier_tree", - "type": { - "fields": [ - { - "name": "root", - "type": { - "kind": "field" - } - }, - { - "name": "next_available_leaf_index", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot" - } - }, - { - "name": "public_data_tree", - "type": { - "fields": [ - { - "name": "root", - "type": { - "kind": "field" - } - }, - { - "name": "next_available_leaf_index", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::partial_state_reference::PartialStateReference" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::state_reference::StateReference" - } - }, - { - "name": "global_variables", - "type": { - "fields": [ - { - "name": "chain_id", - "type": { - "kind": "field" - } - }, - { - "name": "version", - "type": { - "kind": "field" - } - }, - { - "name": "block_number", - "type": { - "kind": "field" - } - }, - { - "name": "slot_number", - "type": { - "kind": "field" - } - }, - { - "name": "timestamp", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 64 - } - }, - { - "name": "coinbase", - "type": { - "fields": [ - { - "name": "inner", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::address::eth_address::EthAddress" - } - }, - { - "name": "fee_recipient", - "type": { - "fields": [ - { - "name": "inner", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::address::aztec_address::AztecAddress" - } - }, - { - "name": "gas_fees", - "type": { - "fields": [ - { - "name": "fee_per_da_gas", - "type": { - "kind": "field" - } - }, - { - "name": "fee_per_l2_gas", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::gas_fees::GasFees" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::global_variables::GlobalVariables" - } - }, - { - "name": "total_fees", - "type": { - "kind": "field" - } - }, - { - "name": "total_mana_used", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::block_header::BlockHeader" - } - }, - { - "name": "tx_context", - "type": { - "fields": [ - { - "name": "chain_id", - "type": { - "kind": "field" - } - }, - { - "name": "version", - "type": { - "kind": "field" - } - }, - { - "name": "gas_settings", - "type": { - "fields": [ - { - "name": "gas_limits", - "type": { - "fields": [ - { - "name": "da_gas", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - }, - { - "name": "l2_gas", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::gas::Gas" - } - }, - { - "name": "teardown_gas_limits", - "type": { - "fields": [ - { - "name": "da_gas", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - }, - { - "name": "l2_gas", - "type": { - "kind": "integer", - "sign": "unsigned", - "width": 32 - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::gas::Gas" - } - }, - { - "name": "max_fees_per_gas", - "type": { - "fields": [ - { - "name": "fee_per_da_gas", - "type": { - "kind": "field" - } - }, - { - "name": "fee_per_l2_gas", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::gas_fees::GasFees" - } - }, - { - "name": "max_priority_fees_per_gas", - "type": { - "fields": [ - { - "name": "fee_per_da_gas", - "type": { - "kind": "field" - } - }, - { - "name": "fee_per_l2_gas", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::gas_fees::GasFees" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::gas_settings::GasSettings" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::transaction::tx_context::TxContext" - } - } - ], - "kind": "struct", - "path": "aztec::protocol_types::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs" - }, - "visibility": "databus" - } - }, - "bytecode": "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", - "debug_symbols": "7ZbfasIwFMbfJde9OP+SJr7KGKNqlUKpUnUwxHdfIiZVF4VZNhC8KTnJ7+R8fCcJ3at5Pd0tP5pusdqoydtetatZtW1WnY/2Cvk4t1lXXQg326rfqgkaB4Wqu7kflgCHQi2atlYTQ4fiB0yW7QkmawbYcgZmje4Es3Z0H0YjFGk/Fk44acgpQTJRCYoeaFPmdmfDcXNBuKDfC4XycuaGM/rlzA1nzMuZG86Uo50RcHSCBckmuIRjAfvXBdzoAsggEWZ2CXYuBwOW0X8/dnyuJ9Mtcqm7fqyv5RM8t3zMyXdEqQTo++odJNiBPoOzF8uU6SRIQpHkqIXGazE6akGw97Wg08PV8s7ASCf5qdXLv6onIIwXhEBQX8jxwbRv2rZZflz8VEH4SP6UGByUwvXJEn4gRx7I0Q/kmN/m+AgDmn96dHpsS+3OEskn+vCz6ptq2tbB0LC662bRXx9uv9ZxJXZg3a9m9XzX16EXQxuCowyFQHjCgxCxheak7ThFXJD1VX3lbw==", - "brillig_names": [ - "store_in_execution_cache_oracle_wrapper", - "enqueue_public_function_call_internal" - ], - "verification_key": "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" - }, - { - "name": "add_to_counter_public", - "is_unconstrained": true, - "custom_attributes": ["public", "internal"], - "abi": { - "error_types": { - "10176877060487216746": { - "error_kind": "string", - "string": "Function add_to_counter_public can only be called internally" - }, - "13699457482007836410": { - "error_kind": "string", - "string": "Not initialized" - }, - "16761564377371454734": { - "error_kind": "string", - "string": "Array index out of bounds" - }, - "17843811134343075018": { - "error_kind": "string", - "string": "Stack too deep" - }, - "206160798890201757": { - "error_kind": "string", - "string": "Storage slot 0 not allowed. Storage slots must start from 1." - }, - "5019202896831570965": { - "error_kind": "string", - "string": "attempt to add with overflow" - } - }, - "parameters": [ - { - "name": "counter_id", - "type": { - "kind": "field" - }, - "visibility": "private" - } - ], - "return_type": null - }, - "bytecode": "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", - "debug_symbols": "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", - "brillig_names": ["add_to_counter_public"] - }, { "name": "get_counter_value", "is_unconstrained": true, @@ -1948,25 +283,21 @@ "parameters": [ { "name": "counter_id", - "type": { - "kind": "field" - }, + "type": { "kind": "field" }, "visibility": "private" } ], "return_type": { - "abi_type": { - "kind": "field" - }, + "abi_type": { "kind": "field" }, "visibility": "public" } }, "bytecode": "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", - "debug_symbols": "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", + "debug_symbols": "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", "brillig_names": ["get_counter_value"] }, { - "name": "compute_note_hash_and_optionally_a_nullifier", + "name": "process_log", "is_unconstrained": true, "custom_attributes": [], "abi": { @@ -1983,75 +314,74 @@ }, "parameters": [ { - "name": "contract_address", + "name": "log_plaintext", "type": { "fields": [ { - "name": "inner", + "name": "storage", "type": { - "kind": "field" + "kind": "array", + "length": 18, + "type": { "kind": "field" } } + }, + { + "name": "len", + "type": { "kind": "integer", "sign": "unsigned", "width": 32 } } ], "kind": "struct", - "path": "aztec::protocol_types::address::aztec_address::AztecAddress" - }, - "visibility": "private" - }, - { - "name": "nonce", - "type": { - "kind": "field" + "path": "std::collections::bounded_vec::BoundedVec" }, "visibility": "private" }, { - "name": "storage_slot", - "type": { - "kind": "field" - }, + "name": "tx_hash", + "type": { "kind": "field" }, "visibility": "private" }, { - "name": "note_type_id", + "name": "unique_note_hashes_in_tx", "type": { - "kind": "field" + "fields": [ + { + "name": "storage", + "type": { + "kind": "array", + "length": 64, + "type": { "kind": "field" } + } + }, + { + "name": "len", + "type": { "kind": "integer", "sign": "unsigned", "width": 32 } + } + ], + "kind": "struct", + "path": "std::collections::bounded_vec::BoundedVec" }, "visibility": "private" }, { - "name": "compute_nullifier", - "type": { - "kind": "boolean" - }, + "name": "first_nullifier_in_tx", + "type": { "kind": "field" }, "visibility": "private" }, { - "name": "serialized_note", + "name": "recipient", "type": { - "kind": "array", - "length": 0, - "type": { - "kind": "field" - } + "fields": [{ "name": "inner", "type": { "kind": "field" } }], + "kind": "struct", + "path": "aztec::protocol_types::address::aztec_address::AztecAddress" }, "visibility": "private" } ], - "return_type": { - "abi_type": { - "kind": "array", - "length": 4, - "type": { - "kind": "field" - } - }, - "visibility": "public" - } + "return_type": null }, - "bytecode": "H4sIAAAAAAAA/9VZ227aQBBdsI2xiYHCH0TqWyvZhOsbUi/5DpTAF/QD/NCX9qvLih37MExUJGaisFK0Zmd95uyZ2Ys3HXcq/eNfJzzHoe65y0J9tqEubyuVIlZpybNzJzy7d8IzuhOesSLPjsDT1zTfEneac6k7zcemEV/yAY7gJfc/AHD2N9RZqLtgVwxIlQmD1MJfl/OXzJ0XZf5PWcBMbfAXhN+3wS+J97e6xcexkN8o1M91q+UzvONLEZ4xeQmXbF2wfWe2CGw/mA1z+CezYd4TJ9KtB2NRzKu1dVxobCmMrfNG7VyrHbaR1rkzzdGKYp4xPpw/8SmoT93y6TFbDLaM2RKwkf6+foR+PPYp9PsK7TwnI3eZw2SnmKPWFjkVG+Afy1zSncckrs99ow11j0HPR6aPxV6B+ljo7/WZvsGfnn1Ja9eUiOmJGpFmfezPbBnY4vrcTx5+x+AHsYhHwvp/Cb9Hoe7BO/T+WPDfY/7PeAttqBHHioQ26u/n5OfwPHCn/PlN/d3lOqV3mF7OpTVbD3/V4Gc2/A+En9vgLwl/YIPfnGUeTPBnJeEXNvw3hD+0yZ/mLDmy4b8n/LEJ/nxP++4n15ZmfQjPE2jXW7ur6pozEfrPGVerM9GE8eH64P7rbVOB61iw8RhOBT9TwY+ElSliPShijT7oGPuKWANFrKEilmYcU0UsTb1yRaxCEUsz7zX1ojhK5zRftqEubyzSOU0Rv5LOaZrf7qQ15VcsaIjjS1j/X0zngQnPakZ7Ds118oG+CyPf1+7X5L8Q+BDvXLDdchm7X6wPm/ViczySVcvZpolnwbjyNvwmwvUY+0t7v3TuU9S6lL77h6CrLzHYCmZLwEYcpe/+oRH/a/RH/2PBxvf/a2M5cZf74YCNG++4tipjbu//pLt54/Vrce3cJP+5u1yv3+t+EfXhZ+lc4DoWbPx8kgt+csHPPWLxO3rU0Oc16RTXrV0rlqt1+48tWosSd37v75j/hPX/E37j2Ki+Zc0/rHbV4Wl32C12r6/zl92E4fvSBZ3+Ab+1O0oNHwAA", - "debug_symbols": "tdfRioQgFAbgd/HaC49aZq+yLIOVDYJYWC0s0buvDbO7w8zl8N8EJ06fIf7I2dngu+16CWmcFtZ+7CxOvVvDlEq1H5x1OcQYrpfH10ycD6tu/cvs0lkuq8sra5XkzKeBtVqUr8cQPWtrefCXRvPbaMxfYyWPT86sRsEVCq5RsEHBDQq2IJiEgMkEkyVMVjBZw+QKJtcw2cDkBibDMkiwDBIsgwTLIMEySLAMEiyD9F4Grbo3lm19oQ2ObnC0hdFS4GjC0RJHKxytcXSFo3FplLg0SlwaJSiNR6m+XA6ui/4+M41b6h9GqPV79k/T1Jyn3g9b9udc9T9SnYdYaa717RYvBZX/I2XKImWhHw==", - "brillig_names": ["compute_note_hash_and_optionally_a_nullifier"] + "bytecode": "H4sIAAAAAAAA/92caVPbMBCGHbABB0LC0fukNy1tHZKQpCctve8L+jlTyJ9oP7j9E7T/tnlBSzZCnaGDNOWtZzxOvMruo7Usr6VVCtH2ttbbC+ZzbI6j5ojz09HgJmWXzTHb31b1qCsLxVggYBwiYBwmYIwJGBMCxhECxlECxjECxpSAsUjAOE7AOEHAWCJgnCRgLBMwVggYpwIwhuCcJuGc8cipY/tQvLPRwW+jhwgYDxMwHiFgPErAeIyA8TgB4wkCxpMEjKcIGE8TMJ4hYDxLwDhHwHiOgPE8AeMFAsaLBIyXCBgvEzBeIWCcJ2C8SsB4jYBxgYDxOgHjDQLGmwSMGQFjlYBxkYCxRsBYJ2BsEDAuETA2CRhbBIxtAsZbBIy3CRjvEDDeJWC8R8B4n4BxmYDxAQHjQwLGFQLGRwSMjwkYnxAwPiVgfEbA+JyA8QUB40sCxlcEjK8JGN8QML4lYHxHwPiegPEDAePHAIwhOD+RcK6ScK4F4ow+W9BDvR0Lt7AwCguPsLAHC2ewMAULP7CwAgsXsDAAifdIbEfieKW3I/EZScVI2EUSLJJMkcSJJEkkISLJD0l0SFJDEhiSrJDEhCShs719rrcjiQRJGkiCQJIBJvExSY5JaEzyYhIVk5SYBMQkGyaxMEmEWmGSA5MIGKTHIDgGmTGIi0FSDEJikA+DaBikwiAQBlkwiCGDBHjJxUskXtLwEoSXDATxCJIRhCLIQxCFIAVBAB6yeIjhIYFOGJ0cOhHcpLgB0LjWoj9v0kh+mGNqjkNK7nERXTW17PrU38randRRP4/8tdToHAuiv9EU/WkY/kwW2q7kff26LmJ32BxX874vV/NBJimzqcpsWmWkPmGud70W1l/VxZLlo0jVRWwXw9iuFSx7+rpomdgvRiHb5vaiZG1PeGz/SN9RkjJ5n6dgyeJ8dz1EliiZXF/YmVfl7LY1ZsmEBZu035LyjWxrRibXNFY6/bXX0Pd3Pft37bVe/R/ba2zJ4nx3Pf62veq2ZbfXJOpv0peKbETJflqyUSX7lfdt1825sP3w9nNX32++n1szDn5tC9to3veBtLthdS5RPtvyjy5vyVIli/NBO0XzPVZ2tC7hSKzyNfO9bI4j6jfy+4rD/ohlf4Dbcc72S+oonzrKo30tmM+Ir9F+vkn5aPe9in3ZfM/2tS21Xf2iP/3Nmqvv88i/IfrHg+iv7+ifCMNfF/2lMP7f0T8Zhr8r+sth9C+J/koY/Q3RPxVE/+JOXKD/XMeOC2bUeY9x7J7jArFftFhDxQUzFo/tHx0XQDbrYK04ZHYfMOuwM+uw49I16VHXlEddxQNax5JHXRWPulKPunxexwmPunz6q+xR15hHXT7bvU9/yXUMOz6VZa44LQqgvxhG/07fL320fhfTdRL7iVX+q+XniSB+7o87SX+mfeGKpXza3uvzWuyXHDzCXXTI9vOHZxuNVrfdarR7IX11abGdFSz9wmqf0+9Eun/R5V3Pflfc59HXmWvMoaz8ii1WsklLliiZMOoxB1dc7JN/L/7X9isOmd0/7/VaTkeDbU3fj+NR/36Oc/91b7a2/8hli9HoT6LBMcXIsp9Y5b+b73Zft997pNvsVLu1TrfT6Kyv1790pi392ofw02+mXHNgmVMAAA==", + "debug_symbols": "tZbLCoMwEEX/ZdZZOFOtrb9SSokaJRCiRC0U8d8bpQ9p13cTuGFyZnXCnak25dTerG+6gYrLTK6r9Gg7H9O8KCqDdc62t/01JevBSbI9GHrt1zyMOoxUHESR8TUVaRKfN9YZKo6yqL/B/D2Y55/BTJarimSGkQVGPsDIKYycwchHGDmHkU8w8hlFZpiDDHOQYQ4yzEGGOcgwBxnmIMMcZJiDDHNQYA4KzEHBOLjEdNfB6tKZV4FoJl/t+sT46M1PtehDV5l6CmYtGd9+sbqcssp4+0FjYEkVyzkuiYue", + "brillig_names": ["process_log"] } ], "outputs": { @@ -2061,10 +391,7 @@ "fields": [ { "name": "contract_name", - "value": { - "kind": "string", - "value": "SimpleLogging" - } + "value": { "kind": "string", "value": "SimpleLogging" } }, { "name": "fields", @@ -2103,20 +430,15 @@ "name": "parameters", "type": { "fields": [ - { - "name": "counter_id", - "type": { - "kind": "field" - } - } + { "name": "counter_id", "type": { "kind": "field" } } ], "kind": "struct", - "path": "SimpleLogging::add_to_counter_public_parameters" + "path": "SimpleLogging::increase_counter_public_parameters" } } ], "kind": "struct", - "path": "SimpleLogging::add_to_counter_public_abi" + "path": "SimpleLogging::increase_counter_public_abi" }, { "fields": [ @@ -2138,116 +460,78 @@ "name": "parameters", "type": { "fields": [ - { - "name": "counter_id", - "type": { - "kind": "field" - } - } - ], - "kind": "struct", - "path": "SimpleLogging::increase_counter_private_parameters" - } - } - ], - "kind": "struct", - "path": "SimpleLogging::increase_counter_private_abi" - }, - { - "fields": [ - { - "name": "parameters", - "type": { - "fields": [ - { - "name": "counter_id", - "type": { - "kind": "field" - } - } + { "name": "counter_id", "type": { "kind": "field" } } ], "kind": "struct", - "path": "SimpleLogging::increase_counter_public_parameters" + "path": "SimpleLogging::add_to_counter_public_parameters" } } ], "kind": "struct", - "path": "SimpleLogging::increase_counter_public_abi" + "path": "SimpleLogging::add_to_counter_public_abi" } ] } }, "file_map": { - "122": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr", - "source": "use dep::protocol_types::{abis::function_selector::FunctionSelector, address::AztecAddress};\n\n#[oracle(enqueuePublicFunctionCall)]\nunconstrained fn enqueue_public_function_call_oracle(\n _contract_address: AztecAddress,\n _function_selector: FunctionSelector,\n _args_hash: Field,\n _side_effect_counter: u32,\n _is_static_call: bool,\n) -> Field {}\n\npub unconstrained fn enqueue_public_function_call_internal(\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field,\n side_effect_counter: u32,\n is_static_call: bool,\n) -> Field {\n enqueue_public_function_call_oracle(\n contract_address,\n function_selector,\n args_hash,\n side_effect_counter,\n is_static_call,\n )\n}\n\n#[oracle(setPublicTeardownFunctionCall)]\nunconstrained fn set_public_teardown_function_call_oracle(\n _contract_address: AztecAddress,\n _function_selector: FunctionSelector,\n _args_hash: Field,\n _side_effect_counter: u32,\n _is_static_call: bool,\n) -> Field {}\n\npub unconstrained fn set_public_teardown_function_call_internal(\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field,\n side_effect_counter: u32,\n is_static_call: bool,\n) -> Field {\n set_public_teardown_function_call_oracle(\n contract_address,\n function_selector,\n args_hash,\n side_effect_counter,\n is_static_call,\n )\n}\n\npub fn notify_set_min_revertible_side_effect_counter(counter: u32) {\n /// Safety: This oracle call returns nothing: we only call it for its side effects. It is therefore always safe\n /// to call.\n unsafe { notify_set_min_revertible_side_effect_counter_oracle_wrapper(counter) };\n}\n\npub unconstrained fn notify_set_min_revertible_side_effect_counter_oracle_wrapper(counter: u32) {\n notify_set_min_revertible_side_effect_counter_oracle(counter);\n}\n\n#[oracle(notifySetMinRevertibleSideEffectCounter)]\nunconstrained fn notify_set_min_revertible_side_effect_counter_oracle(_counter: u32) {}\n" - }, "123": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/oracle/execution.nr", + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/aztec-nr/aztec/src/oracle/execution.nr", "source": "use dep::protocol_types::address::AztecAddress;\n\n#[oracle(getContractAddress)]\nunconstrained fn get_contract_address_oracle() -> AztecAddress {}\n\n#[oracle(getBlockNumber)]\nunconstrained fn get_block_number_oracle() -> u32 {}\n\n#[oracle(getChainId)]\nunconstrained fn get_chain_id_oracle() -> Field {}\n\n#[oracle(getVersion)]\nunconstrained fn get_version_oracle() -> Field {}\n\npub unconstrained fn get_contract_address() -> AztecAddress {\n get_contract_address_oracle()\n}\n\npub unconstrained fn get_block_number() -> u32 {\n get_block_number_oracle()\n}\n\npub unconstrained fn get_chain_id() -> Field {\n get_chain_id_oracle()\n}\n\npub unconstrained fn get_version() -> Field {\n get_version_oracle()\n}\n" }, - "124": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/oracle/execution_cache.nr", - "source": "/// Stores values represented as slice in execution cache to be later obtained by its hash.\npub fn store(values: [Field]) {\n /// Safety: This oracle call returns nothing: we only call it for its side effects. It is therefore always safe\n /// to call. When loading the values, however, the caller must check that the values are indeed the preimage.\n unsafe { store_in_execution_cache_oracle_wrapper(values) };\n}\n\n/// Stores values represented as array in execution cache to be later obtained by its hash.\npub fn store_array(values: [Field; N]) {\n /// Safety: This oracle call returns nothing: we only call it for its side effects. It is therefore always safe\n /// to call. When loading the values, however, the caller must check that the values are indeed the preimage.\n unsafe { store_array_in_execution_cache_oracle_wrapper(values) };\n}\n\npub unconstrained fn store_in_execution_cache_oracle_wrapper(values: [Field]) {\n let _ = store_in_execution_cache_oracle(values);\n}\n\npub unconstrained fn store_array_in_execution_cache_oracle_wrapper(values: [Field; N]) {\n let _ = store_array_in_execution_cache_oracle(values);\n}\n\npub unconstrained fn load(hash: Field) -> [Field; N] {\n load_from_execution_cache_oracle(hash)\n}\n\n#[oracle(storeInExecutionCache)]\nunconstrained fn store_in_execution_cache_oracle(_values: [Field]) -> Field {}\n\n#[oracle(storeArrayInExecutionCache)]\nunconstrained fn store_array_in_execution_cache_oracle(_args: [Field; N]) -> Field {}\n\n#[oracle(loadFromExecutionCache)]\nunconstrained fn load_from_execution_cache_oracle(_hash: Field) -> [Field; N] {}\n" - }, "125": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/oracle/get_contract_instance.nr", + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/aztec-nr/aztec/src/oracle/get_contract_instance.nr", "source": "use dep::protocol_types::{\n address::AztecAddress, constants::CONTRACT_INSTANCE_LENGTH, contract_class_id::ContractClassId,\n contract_instance::ContractInstance,\n};\n\n// NOTE: this is for use in private only\n#[oracle(getContractInstance)]\nunconstrained fn get_contract_instance_oracle(\n _address: AztecAddress,\n) -> [Field; CONTRACT_INSTANCE_LENGTH] {}\n\n// NOTE: this is for use in private only\nunconstrained fn get_contract_instance_internal(\n address: AztecAddress,\n) -> [Field; CONTRACT_INSTANCE_LENGTH] {\n get_contract_instance_oracle(address)\n}\n\n// NOTE: this is for use in private only\npub fn get_contract_instance(address: AztecAddress) -> ContractInstance {\n /// Safety: The to_address function combines all values in the instance object to produce an address,\n /// so by checking that we get the expected address we validate the entire struct.\n let instance =\n unsafe { ContractInstance::deserialize(get_contract_instance_internal(address)) };\n assert_eq(instance.to_address(), address);\n\n instance\n}\n\n// These oracles each return a ContractInstance member\n// plus a boolean indicating whether the instance was found.\n#[oracle(avmOpcodeGetContractInstanceDeployer)]\nunconstrained fn get_contract_instance_deployer_oracle_avm(\n _address: AztecAddress,\n) -> (Field, bool) {}\n#[oracle(avmOpcodeGetContractInstanceClassId)]\nunconstrained fn get_contract_instance_class_id_oracle_avm(\n _address: AztecAddress,\n) -> (Field, bool) {}\n#[oracle(avmOpcodeGetContractInstanceInitializationHash)]\nunconstrained fn get_contract_instance_initialization_hash_oracle_avm(\n _address: AztecAddress,\n) -> (Field, bool) {}\n\npub unconstrained fn get_contract_instance_deployer_internal_avm(\n address: AztecAddress,\n) -> (Field, bool) {\n get_contract_instance_deployer_oracle_avm(address)\n}\npub unconstrained fn get_contract_instance_class_id_internal_avm(\n address: AztecAddress,\n) -> (Field, bool) {\n get_contract_instance_class_id_oracle_avm(address)\n}\npub unconstrained fn get_contract_instance_initialization_hash_internal_avm(\n address: AztecAddress,\n) -> (Field, bool) {\n get_contract_instance_initialization_hash_oracle_avm(address)\n}\n\npub fn get_contract_instance_deployer_avm(address: AztecAddress) -> Option {\n /// Safety: AVM opcodes are constrained by the AVM itself\n let (member, exists) = unsafe { get_contract_instance_deployer_internal_avm(address) };\n if exists {\n Option::some(AztecAddress::from_field(member))\n } else {\n Option::none()\n }\n}\npub fn get_contract_instance_class_id_avm(address: AztecAddress) -> Option {\n /// Safety: AVM opcodes are constrained by the AVM itself\n let (member, exists) = unsafe { get_contract_instance_class_id_internal_avm(address) };\n if exists {\n Option::some(ContractClassId::from_field(member))\n } else {\n Option::none()\n }\n}\npub fn get_contract_instance_initialization_hash_avm(address: AztecAddress) -> Option {\n /// Safety: AVM opcodes are constrained by the AVM itself\n let (member, exists) =\n unsafe { get_contract_instance_initialization_hash_internal_avm(address) };\n if exists {\n Option::some(member)\n } else {\n Option::none()\n }\n}\n" }, "135": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/oracle/notes.nr", + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/aztec-nr/aztec/src/oracle/notes.nr", "source": "use crate::{note::{note_header::NoteHeader, note_interface::NoteInterface}, utils::array};\n\nuse dep::protocol_types::{\n address::AztecAddress,\n indexed_tagging_secret::{INDEXED_TAGGING_SECRET_LENGTH, IndexedTaggingSecret},\n};\n\n/// Notifies the simulator that a note has been created, so that it can be returned in future read requests in the same\n/// transaction. This note should only be added to the non-volatile database if found in an actual block.\npub fn notify_created_note(\n storage_slot: Field,\n note_type_id: Field,\n serialized_note: [Field; N],\n note_hash: Field,\n counter: u32,\n) {\n /// Safety: This oracle call returns nothing: we only call it for its side effects. It is therefore always safe\n /// to call.\n unsafe {\n notify_created_note_oracle_wrapper(\n storage_slot,\n note_type_id,\n serialized_note,\n note_hash,\n counter,\n )\n };\n}\n\n/// Notifies the simulator that a note has been nullified, so that it is no longer returned in future read requests in\n/// the same transaction. This note should only be removed to the non-volatile database if its nullifier is found in an\n/// actual block.\npub fn notify_nullified_note(nullifier: Field, note_hash: Field, counter: u32) {\n /// Safety: This oracle call returns nothing: we only call it for its side effects. It is therefore always safe\n /// to call.\n unsafe { notify_nullified_note_oracle_wrapper(nullifier, note_hash, counter) };\n}\n\n/// Notifies the simulator that a non-note nullifier has been created, so that it can be used for note nonces.\npub fn notify_created_nullifier(nullifier: Field) {\n // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe to call.\n unsafe { notify_created_nullifier_oracle_wrapper(nullifier) };\n}\n\nunconstrained fn notify_created_note_oracle_wrapper(\n storage_slot: Field,\n note_type_id: Field,\n serialized_note: [Field; N],\n note_hash: Field,\n counter: u32,\n) {\n let _ = notify_created_note_oracle(\n storage_slot,\n note_type_id,\n serialized_note,\n note_hash,\n counter,\n );\n}\n\n#[oracle(notifyCreatedNote)]\nunconstrained fn notify_created_note_oracle(\n _storage_slot: Field,\n _note_type_id: Field,\n _serialized_note: [Field; N],\n _note_hash: Field,\n _counter: u32,\n) -> Field {}\n\nunconstrained fn notify_nullified_note_oracle_wrapper(\n nullifier: Field,\n note_hash: Field,\n counter: u32,\n) {\n let _ = notify_nullified_note_oracle(nullifier, note_hash, counter);\n}\n\n#[oracle(notifyNullifiedNote)]\nunconstrained fn notify_nullified_note_oracle(\n _nullifier: Field,\n _note_hash: Field,\n _counter: u32,\n) -> Field {}\n\nunconstrained fn notify_created_nullifier_oracle_wrapper(nullifier: Field) {\n let _ = notify_created_nullifier_oracle(nullifier);\n}\n\n#[oracle(notifyCreatedNullifier)]\nunconstrained fn notify_created_nullifier_oracle(_nullifier: Field) -> Field {}\n\n#[oracle(getNotes)]\nunconstrained fn get_notes_oracle(\n _storage_slot: Field,\n _num_selects: u8,\n _select_by_indexes: [u8; N],\n _select_by_offsets: [u8; N],\n _select_by_lengths: [u8; N],\n _select_values: [Field; N],\n _select_comparators: [u8; N],\n _sort_by_indexes: [u8; N],\n _sort_by_offsets: [u8; N],\n _sort_by_lengths: [u8; N],\n _sort_order: [u8; N],\n _limit: u32,\n _offset: u32,\n _status: u8,\n _return_size: u32,\n _placeholder_fields: [Field; S],\n) -> [Field; S] {}\n\nunconstrained fn get_notes_oracle_wrapper(\n storage_slot: Field,\n num_selects: u8,\n select_by_indexes: [u8; N],\n select_by_offsets: [u8; N],\n select_by_lengths: [u8; N],\n select_values: [Field; N],\n select_comparators: [u8; N],\n sort_by_indexes: [u8; N],\n sort_by_offsets: [u8; N],\n sort_by_lengths: [u8; N],\n sort_order: [u8; N],\n limit: u32,\n offset: u32,\n status: u8,\n mut placeholder_fields: [Field; S],\n) -> [Field; S] {\n let return_size = placeholder_fields.len() as u32;\n get_notes_oracle(\n storage_slot,\n num_selects,\n select_by_indexes,\n select_by_offsets,\n select_by_lengths,\n select_values,\n select_comparators,\n sort_by_indexes,\n sort_by_offsets,\n sort_by_lengths,\n sort_order,\n limit,\n offset,\n status,\n return_size,\n placeholder_fields,\n )\n}\n\npub unconstrained fn get_notes(\n storage_slot: Field,\n num_selects: u8,\n select_by_indexes: [u8; M],\n select_by_offsets: [u8; M],\n select_by_lengths: [u8; M],\n select_values: [Field; M],\n select_comparators: [u8; M],\n sort_by_indexes: [u8; M],\n sort_by_offsets: [u8; M],\n sort_by_lengths: [u8; M],\n sort_order: [u8; M],\n limit: u32,\n offset: u32,\n status: u8,\n mut placeholder_opt_notes: [Option; S], // TODO: Remove it and use `limit` to initialize the note array.\n placeholder_fields: [Field; NS], // TODO: Remove it and use `limit` to initialize the note array.\n _placeholder_note_length: [Field; N], // Turbofish hack? Compiler breaks calculating read_offset unless we add this parameter\n) -> [Option; S]\nwhere\n Note: NoteInterface,\n{\n sync_notes_oracle_wrapper();\n let fields = get_notes_oracle_wrapper(\n storage_slot,\n num_selects,\n select_by_indexes,\n select_by_offsets,\n select_by_lengths,\n select_values,\n select_comparators,\n sort_by_indexes,\n sort_by_offsets,\n sort_by_lengths,\n sort_order,\n limit,\n offset,\n status,\n placeholder_fields,\n );\n let num_notes = fields[0] as u32;\n let contract_address = AztecAddress::from_field(fields[1]);\n for i in 0..placeholder_opt_notes.len() {\n if i < num_notes {\n // lengths named as per typescript.\n let return_header_length: u32 = 2; // num_notes & contract_address.\n let extra_preimage_length: u32 = 2; // nonce & note_hash_counter.\n let read_offset: u32 = return_header_length + i * (N + extra_preimage_length);\n\n let nonce = fields[read_offset];\n let note_hash_counter = fields[read_offset + 1] as u32;\n let note_content = array::subarray(fields, read_offset + 2);\n\n let mut note = Note::deserialize_content(note_content);\n note.set_header(NoteHeader { contract_address, nonce, storage_slot, note_hash_counter });\n\n placeholder_opt_notes[i] = Option::some(note);\n };\n }\n placeholder_opt_notes\n}\n\n/// Returns true if the nullifier exists. Note that a `true` value can be constrained by proving existence of the\n/// nullifier, but a `false` value should not be relied upon since other transactions may emit this nullifier before the\n/// current transaction is included in a block. While this might seem of little use at first, certain design patterns\n/// benefit from this abstraction (see e.g. `PrivateMutable`).\npub unconstrained fn check_nullifier_exists(inner_nullifier: Field) -> bool {\n check_nullifier_exists_oracle(inner_nullifier) == 1\n}\n\n#[oracle(checkNullifierExists)]\nunconstrained fn check_nullifier_exists_oracle(_inner_nullifier: Field) -> Field {}\n\n/// Same as `get_indexed_tagging_secret_as_sender`, except it returns the derived tag, ready to be included in a log.\npub unconstrained fn get_app_tag_as_sender(sender: AztecAddress, recipient: AztecAddress) -> Field {\n get_indexed_tagging_secret_as_sender(sender, recipient).compute_tag(recipient)\n}\n\n/// Returns the tagging secret for a given sender and recipient pair, siloed for the current contract address.\n/// Includes the last known index used to send a note tagged with this secret.\n/// For this to work, PXE must know the ivsk_m of the sender.\n/// For the recipient's side, only the address is needed.\npub unconstrained fn get_indexed_tagging_secret_as_sender(\n sender: AztecAddress,\n recipient: AztecAddress,\n) -> IndexedTaggingSecret {\n let result = get_indexed_tagging_secret_as_sender_oracle(sender, recipient);\n IndexedTaggingSecret::deserialize(result)\n}\n\n#[oracle(getIndexedTaggingSecretAsSender)]\nunconstrained fn get_indexed_tagging_secret_as_sender_oracle(\n _sender: AztecAddress,\n _recipient: AztecAddress,\n) -> [Field; INDEXED_TAGGING_SECRET_LENGTH] {}\n\n/// Notifies the simulator that a tag has been used in a note, and to therefore increment the associated index so that\n/// future notes get a different tag and can be discovered by the recipient.\n/// This change should only be persisted in a non-volatile database if the tagged log is found in an actual block -\n/// otherwise e.g. a reverting transaction can cause the sender to accidentally skip indices and later produce notes\n/// that are not found by the recipient.\npub fn increment_app_tagging_secret_index_as_sender(sender: AztecAddress, recipient: AztecAddress) {\n /// Safety: This oracle call returns nothing: we only call it for its side effects. It is therefore always safe\n /// to call.\n unsafe {\n increment_app_tagging_secret_index_as_sender_wrapper(sender, recipient);\n }\n}\n\nunconstrained fn increment_app_tagging_secret_index_as_sender_wrapper(\n sender: AztecAddress,\n recipient: AztecAddress,\n) {\n increment_app_tagging_secret_index_as_sender_oracle(sender, recipient);\n}\n\n#[oracle(incrementAppTaggingSecretIndexAsSender)]\nunconstrained fn increment_app_tagging_secret_index_as_sender_oracle(\n _sender: AztecAddress,\n _recipient: AztecAddress,\n) {}\n\n/// Finds new notes that may have been sent to all registered accounts in PXE in the current contract and makes them available\n/// for later querying via the `get_notes` oracle.\npub fn sync_notes() {\n /// Safety: This oracle call returns nothing: we only call it for its side effects. It is therefore always safe\n /// to call.\n unsafe {\n sync_notes_oracle_wrapper();\n }\n}\n\nunconstrained fn sync_notes_oracle_wrapper() {\n sync_notes_oracle();\n}\n\n#[oracle(syncNotes)]\nunconstrained fn sync_notes_oracle() {}\n" }, "138": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/oracle/storage.nr", - "source": "use dep::protocol_types::{address::AztecAddress, traits::Deserialize};\n\n#[oracle(storageRead)]\nunconstrained fn storage_read_oracle(\n address: Field,\n storage_slot: Field,\n block_number: Field,\n length: Field,\n) -> [Field; N] {}\n\npub unconstrained fn raw_storage_read(\n address: AztecAddress,\n storage_slot: Field,\n block_number: u32,\n) -> [Field; N] {\n storage_read_oracle(\n address.to_field(),\n storage_slot,\n block_number as Field,\n N as Field,\n )\n}\n\npub unconstrained fn storage_read(\n address: AztecAddress,\n storage_slot: Field,\n block_number: u32,\n) -> T\nwhere\n T: Deserialize,\n{\n T::deserialize(raw_storage_read(address, storage_slot, block_number))\n}\n\nmod tests {\n use crate::oracle::storage::{raw_storage_read, storage_read};\n use dep::protocol_types::address::AztecAddress;\n\n use crate::test::mocks::mock_struct::MockStruct;\n use std::test::OracleMock;\n\n global address: AztecAddress = AztecAddress::from_field(29);\n global slot: Field = 7;\n global block_number: u32 = 17;\n\n #[test]\n unconstrained fn test_raw_storage_read() {\n let written = MockStruct { a: 13, b: 42 };\n\n let _ = OracleMock::mock(\"storageRead\").returns(written.serialize());\n\n let read: [Field; 2] = raw_storage_read(address, slot, block_number);\n assert_eq(read[0], 13);\n assert_eq(read[1], 42);\n }\n\n #[test]\n unconstrained fn test_storage_read() {\n let written = MockStruct { a: 13, b: 42 };\n\n let _ = OracleMock::mock(\"storageRead\").returns(written.serialize());\n\n let read: MockStruct = storage_read(address, slot, block_number);\n assert_eq(read.a, 13);\n assert_eq(read.b, 42);\n }\n}\n" + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/aztec-nr/aztec/src/oracle/storage.nr", + "source": "use dep::protocol_types::{address::AztecAddress, traits::Packable};\n\n#[oracle(storageRead)]\nunconstrained fn storage_read_oracle(\n address: Field,\n storage_slot: Field,\n block_number: Field,\n length: Field,\n) -> [Field; N] {}\n\npub unconstrained fn raw_storage_read(\n address: AztecAddress,\n storage_slot: Field,\n block_number: u32,\n) -> [Field; N] {\n storage_read_oracle(\n address.to_field(),\n storage_slot,\n block_number as Field,\n N as Field,\n )\n}\n\npub unconstrained fn storage_read(\n address: AztecAddress,\n storage_slot: Field,\n block_number: u32,\n) -> T\nwhere\n T: Packable,\n{\n T::unpack(raw_storage_read(address, storage_slot, block_number))\n}\n\nmod tests {\n use crate::oracle::storage::{raw_storage_read, storage_read};\n use dep::protocol_types::{address::AztecAddress, traits::{FromField, Packable}};\n\n use crate::test::mocks::mock_struct::MockStruct;\n use std::test::OracleMock;\n\n global address: AztecAddress = AztecAddress::from_field(29);\n global slot: Field = 7;\n global block_number: u32 = 17;\n\n #[test]\n unconstrained fn test_raw_storage_read() {\n let written = MockStruct { a: 13, b: 42 };\n\n let _ = OracleMock::mock(\"storageRead\").returns(written.pack());\n\n let read: [Field; 2] = raw_storage_read(address, slot, block_number);\n assert_eq(read[0], 13);\n assert_eq(read[1], 42);\n }\n\n #[test]\n unconstrained fn test_storage_read() {\n let written = MockStruct { a: 13, b: 42 };\n\n let _ = OracleMock::mock(\"storageRead\").returns(written.pack());\n\n let read: MockStruct = storage_read(address, slot, block_number);\n assert_eq(read.a, 13);\n assert_eq(read.b, 42);\n }\n}\n" }, "141": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/state_vars/map.nr", - "source": "use crate::state_vars::storage::Storage;\nuse dep::protocol_types::{\n storage::map::derive_storage_slot_in_map,\n traits::{Deserialize, Serialize, ToField},\n};\n\n// docs:start:map\npub struct Map {\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V,\n}\n// docs:end:map\n\nimpl Storage for Map\nwhere\n T: Serialize + Deserialize,\n{\n fn get_storage_slot(self) -> Field {\n self.storage_slot\n }\n}\n\nimpl Map {\n // docs:start:new\n pub fn new(\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V,\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Map { context, storage_slot, state_var_constructor }\n }\n // docs:end:new\n\n // docs:start:at\n pub fn at(self, key: K) -> V\n where\n K: ToField,\n {\n // TODO(#1204): use a generator index for the storage slot\n let derived_storage_slot = derive_storage_slot_in_map(self.storage_slot, key);\n\n let state_var_constructor = self.state_var_constructor;\n state_var_constructor(self.context, derived_storage_slot)\n }\n // docs:end:at\n}\n" + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/aztec-nr/aztec/src/state_vars/map.nr", + "source": "use crate::state_vars::storage::Storage;\nuse dep::protocol_types::{storage::map::derive_storage_slot_in_map, traits::{Packable, ToField}};\n\n// docs:start:map\npub struct Map {\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V,\n}\n// docs:end:map\n\nimpl Storage for Map\nwhere\n T: Packable,\n{\n fn get_storage_slot(self) -> Field {\n self.storage_slot\n }\n}\n\nimpl Map {\n // docs:start:new\n pub fn new(\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V,\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Map { context, storage_slot, state_var_constructor }\n }\n // docs:end:new\n\n // docs:start:at\n pub fn at(self, key: K) -> V\n where\n K: ToField,\n {\n // TODO(#1204): use a generator index for the storage slot\n let derived_storage_slot = derive_storage_slot_in_map(self.storage_slot, key);\n\n let state_var_constructor = self.state_var_constructor;\n state_var_constructor(self.context, derived_storage_slot)\n }\n // docs:end:at\n}\n" }, "149": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr", - "source": "use crate::context::{PublicContext, UnconstrainedContext};\nuse crate::state_vars::storage::Storage;\nuse dep::protocol_types::traits::{Deserialize, Serialize};\n\n// docs:start:public_mutable_struct\npub struct PublicMutable {\n context: Context,\n storage_slot: Field,\n}\n// docs:end:public_mutable_struct\n\nimpl Storage for PublicMutable\nwhere\n T: Serialize + Deserialize,\n{\n fn get_storage_slot(self) -> Field {\n self.storage_slot\n }\n}\n\nimpl PublicMutable {\n // docs:start:public_mutable_struct_new\n pub fn new(\n // Note: Passing the contexts to new(...) just to have an interface compatible with a Map.\n context: Context,\n storage_slot: Field,\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n PublicMutable { context, storage_slot }\n }\n // docs:end:public_mutable_struct_new\n}\n\nimpl PublicMutable\nwhere\n T: Serialize + Deserialize,\n{\n // docs:start:public_mutable_struct_read\n pub fn read(self) -> T {\n self.context.storage_read(self.storage_slot)\n }\n // docs:end:public_mutable_struct_read\n\n // docs:start:public_mutable_struct_write\n pub fn write(self, value: T) {\n self.context.storage_write(self.storage_slot, value);\n }\n // docs:end:public_mutable_struct_write\n}\n\nimpl PublicMutable\nwhere\n T: Deserialize,\n{\n pub unconstrained fn read(self) -> T {\n self.context.storage_read(self.storage_slot)\n }\n}\n" + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr", + "source": "use crate::context::{PublicContext, UnconstrainedContext};\nuse crate::state_vars::storage::Storage;\nuse dep::protocol_types::traits::Packable;\n\n// docs:start:public_mutable_struct\npub struct PublicMutable {\n context: Context,\n storage_slot: Field,\n}\n// docs:end:public_mutable_struct\n\nimpl Storage for PublicMutable\nwhere\n T: Packable,\n{\n fn get_storage_slot(self) -> Field {\n self.storage_slot\n }\n}\n\nimpl PublicMutable {\n // docs:start:public_mutable_struct_new\n pub fn new(\n // Note: Passing the contexts to new(...) just to have an interface compatible with a Map.\n context: Context,\n storage_slot: Field,\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n PublicMutable { context, storage_slot }\n }\n // docs:end:public_mutable_struct_new\n}\n\nimpl PublicMutable\nwhere\n T: Packable,\n{\n // docs:start:public_mutable_struct_read\n pub fn read(self) -> T {\n self.context.storage_read(self.storage_slot)\n }\n // docs:end:public_mutable_struct_read\n\n // docs:start:public_mutable_struct_write\n pub fn write(self, value: T) {\n self.context.storage_write(self.storage_slot, value);\n }\n // docs:end:public_mutable_struct_write\n}\n\nimpl PublicMutable\nwhere\n T: Packable,\n{\n pub unconstrained fn read(self) -> T {\n self.context.storage_read(self.storage_slot)\n }\n}\n" }, "192": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/noir-protocol-circuits/crates/types/src/abis/function_selector.nr", + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/noir-protocol-circuits/crates/types/src/abis/function_selector.nr", "source": "use crate::traits::{Deserialize, Empty, FromField, Serialize, ToField};\n\npub struct FunctionSelector {\n // 1st 4-bytes of abi-encoding of function.\n pub inner: u32,\n}\n\nimpl Eq for FunctionSelector {\n fn eq(self, function_selector: FunctionSelector) -> bool {\n function_selector.inner == self.inner\n }\n}\n\nimpl Serialize<1> for FunctionSelector {\n fn serialize(self: Self) -> [Field; 1] {\n [self.inner as Field]\n }\n}\n\nimpl Deserialize<1> for FunctionSelector {\n fn deserialize(fields: [Field; 1]) -> Self {\n Self { inner: fields[0] as u32 }\n }\n}\n\nimpl FromField for FunctionSelector {\n fn from_field(field: Field) -> Self {\n Self { inner: field as u32 }\n }\n}\n\nimpl ToField for FunctionSelector {\n fn to_field(self) -> Field {\n self.inner as Field\n }\n}\n\nimpl Empty for FunctionSelector {\n fn empty() -> Self {\n Self { inner: 0 as u32 }\n }\n}\n\nimpl FunctionSelector {\n pub fn from_u32(value: u32) -> Self {\n Self { inner: value }\n }\n\n pub fn from_signature(signature: str) -> Self {\n let bytes = signature.as_bytes();\n let hash = crate::hash::poseidon2_hash_bytes(bytes);\n\n // `hash` is automatically truncated to fit within 32 bits.\n FunctionSelector::from_field(hash)\n }\n\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n}\n\n#[test]\nfn test_is_valid_selector() {\n let selector = FunctionSelector::from_signature(\"IS_VALID()\");\n assert_eq(selector.to_field(), 0x73cdda47);\n}\n\n#[test]\nfn test_long_selector() {\n let selector =\n FunctionSelector::from_signature(\"foo_and_bar_and_baz_and_foo_bar_baz_and_bar_foo\");\n assert_eq(selector.to_field(), 0x7590a997);\n}\n" }, - "233": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr", - "source": "use crate::{\n abis::function_selector::FunctionSelector,\n address::{\n partial_address::PartialAddress, salted_initialization_hash::SaltedInitializationHash,\n },\n constants::{\n AZTEC_ADDRESS_LENGTH, FUNCTION_TREE_HEIGHT, GENERATOR_INDEX__CONTRACT_ADDRESS_V1,\n MAX_FIELD_VALUE,\n },\n contract_class_id::ContractClassId,\n hash::{poseidon2_hash_with_separator, private_functions_root_from_siblings},\n merkle_tree::membership::MembershipWitness,\n public_keys::{IvpkM, NpkM, OvpkM, PublicKeys, ToPoint, TpkM},\n traits::{Deserialize, Empty, FromField, Serialize, ToField},\n};\n\n// We do below because `use crate::point::Point;` does not work\nuse dep::std::embedded_curve_ops::EmbeddedCurvePoint as Point;\n\nuse crate::public_keys::AddressPoint;\nuse ec::{pow, sqrt};\nuse std::{\n embedded_curve_ops::{EmbeddedCurveScalar, fixed_base_scalar_mul as derive_public_key},\n ops::Add,\n};\n\n// Aztec address\npub struct AztecAddress {\n pub inner: Field,\n}\n\nimpl Eq for AztecAddress {\n fn eq(self, other: Self) -> bool {\n self.to_field() == other.to_field()\n }\n}\n\nimpl Empty for AztecAddress {\n fn empty() -> Self {\n Self { inner: 0 }\n }\n}\n\nimpl ToField for AztecAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl FromField for AztecAddress {\n fn from_field(value: Field) -> AztecAddress {\n AztecAddress { inner: value }\n }\n}\n\nimpl Serialize for AztecAddress {\n fn serialize(self: Self) -> [Field; AZTEC_ADDRESS_LENGTH] {\n [self.to_field()]\n }\n}\n\nimpl Deserialize for AztecAddress {\n fn deserialize(fields: [Field; AZTEC_ADDRESS_LENGTH]) -> Self {\n FromField::from_field(fields[0])\n }\n}\n\nimpl AztecAddress {\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n\n pub fn to_address_point(self) -> AddressPoint {\n // We compute the address point by taking our address, setting it to x, and then solving for y in the\n // equation which defines our bn curve:\n // y^2 = x^3 - 17; x = address\n let x = self.inner;\n let y_squared = pow(x, 3) - 17;\n\n // TODO (#8970): Handle cases where we cannot recover a point from an address\n let mut y = sqrt(y_squared);\n\n // If we get a negative y coordinate (any y where y > MAX_FIELD_VALUE / 2), we pin it to the\n // positive one (any value where y <= MAX_FIELD_VALUE / 2) by subtracting it from the Field modulus\n // note: The field modulus is MAX_FIELD_VALUE + 1\n if (!(y.lt(MAX_FIELD_VALUE / 2) | y.eq(MAX_FIELD_VALUE / 2))) {\n y = (MAX_FIELD_VALUE + 1) - y;\n }\n\n AddressPoint { inner: Point { x: self.inner, y, is_infinite: false } }\n }\n\n pub fn compute(public_keys: PublicKeys, partial_address: PartialAddress) -> AztecAddress {\n let public_keys_hash = public_keys.hash();\n\n let pre_address = poseidon2_hash_with_separator(\n [public_keys_hash.to_field(), partial_address.to_field()],\n GENERATOR_INDEX__CONTRACT_ADDRESS_V1,\n );\n\n let address_point = derive_public_key(EmbeddedCurveScalar::from_field(pre_address)).add(\n public_keys.ivpk_m.to_point(),\n );\n\n // Note that our address is only the x-coordinate of the full address_point. This is okay because when people want to encrypt something and send it to us\n // they can recover our full point using the x-coordinate (our address itself). To do this, they recompute the y-coordinate according to the equation y^2 = x^3 - 17.\n // When they do this, they may get a positive y-coordinate (a value that is less than or equal to MAX_FIELD_VALUE / 2) or\n // a negative y-coordinate (a value that is more than MAX_FIELD_VALUE), and we cannot dictate which one they get and hence the recovered point may sometimes be different than the one\n // our secrect can decrypt. Regardless though, they should and will always encrypt using point with the positive y-coordinate by convention.\n // This ensures that everyone encrypts to the same point given an arbitrary x-coordinate (address). This is allowed because even though our original point may not have a positive y-coordinate,\n // with our original secret, we will be able to derive the secret to the point with the flipped (and now positive) y-coordinate that everyone encrypts to.\n AztecAddress::from_field(address_point.x)\n }\n\n pub fn compute_from_private_function(\n function_selector: FunctionSelector,\n function_vk_hash: Field,\n function_leaf_membership_witness: MembershipWitness,\n contract_class_artifact_hash: Field,\n contract_class_public_bytecode_commitment: Field,\n salted_initialization_hash: SaltedInitializationHash,\n public_keys: PublicKeys,\n ) -> Self {\n let private_functions_root = private_functions_root_from_siblings(\n function_selector,\n function_vk_hash,\n function_leaf_membership_witness.leaf_index,\n function_leaf_membership_witness.sibling_path,\n );\n\n let contract_class_id = ContractClassId::compute(\n contract_class_artifact_hash,\n private_functions_root,\n contract_class_public_bytecode_commitment,\n );\n\n // Compute contract address using the preimage which includes the class_id.\n let partial_address = PartialAddress::compute_from_salted_initialization_hash(\n contract_class_id,\n salted_initialization_hash,\n );\n\n AztecAddress::compute(public_keys, partial_address)\n }\n\n pub fn is_zero(self) -> bool {\n self.inner == 0\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\n#[test]\nfn compute_address_from_partial_and_pub_keys() {\n let public_keys = PublicKeys {\n npk_m: NpkM {\n inner: Point {\n x: 0x22f7fcddfa3ce3e8f0cc8e82d7b94cdd740afa3e77f8e4a63ea78a239432dcab,\n y: 0x0471657de2b6216ade6c506d28fbc22ba8b8ed95c871ad9f3e3984e90d9723a7,\n is_infinite: false,\n },\n },\n ivpk_m: IvpkM {\n inner: Point {\n x: 0x111223493147f6785514b1c195bb37a2589f22a6596d30bb2bb145fdc9ca8f1e,\n y: 0x273bbffd678edce8fe30e0deafc4f66d58357c06fd4a820285294b9746c3be95,\n is_infinite: false,\n },\n },\n ovpk_m: OvpkM {\n inner: Point {\n x: 0x09115c96e962322ffed6522f57194627136b8d03ac7469109707f5e44190c484,\n y: 0x0c49773308a13d740a7f0d4f0e6163b02c5a408b6f965856b6a491002d073d5b,\n is_infinite: false,\n },\n },\n tpk_m: TpkM {\n inner: Point {\n x: 0x00d3d81beb009873eb7116327cf47c612d5758ef083d4fda78e9b63980b2a762,\n y: 0x2f567d22d2b02fe1f4ad42db9d58a36afd1983e7e2909d1cab61cafedad6193a,\n is_infinite: false,\n },\n },\n };\n\n let partial_address = PartialAddress::from_field(\n 0x0a7c585381b10f4666044266a02405bf6e01fa564c8517d4ad5823493abd31de,\n );\n\n let address = AztecAddress::compute(public_keys, partial_address);\n\n // The following value was generated by `derivation.test.ts`.\n // --> Run the test with AZTEC_GENERATE_TEST_DATA=1 flag to update test data.\n let expected_computed_address_from_partial_and_pubkeys =\n 0x24e4646f58b9fbe7d38e317db8d5636c423fbbdfbe119fc190fe9c64747e0c62;\n assert(address.to_field() == expected_computed_address_from_partial_and_pubkeys);\n}\n\n#[test]\nfn compute_preaddress_from_partial_and_pub_keys() {\n let pre_address = poseidon2_hash_with_separator([1, 2], GENERATOR_INDEX__CONTRACT_ADDRESS_V1);\n let expected_computed_preaddress_from_partial_and_pubkey =\n 0x23ce9be3fa3c846b0f9245cc796902e731d04f086e8a42473bb29e405fc98075;\n assert(pre_address == expected_computed_preaddress_from_partial_and_pubkey);\n}\n\n#[test]\nfn from_field_to_field() {\n let address = AztecAddress { inner: 37 };\n assert_eq(FromField::from_field(address.to_field()), address);\n}\n\n#[test]\nfn serde() {\n let address = AztecAddress { inner: 37 };\n assert_eq(Deserialize::deserialize(address.serialize()), address);\n}\n" + "234": { + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr", + "source": "use crate::{\n abis::function_selector::FunctionSelector,\n address::{\n partial_address::PartialAddress, salted_initialization_hash::SaltedInitializationHash,\n },\n constants::{\n AZTEC_ADDRESS_LENGTH, FUNCTION_TREE_HEIGHT, GENERATOR_INDEX__CONTRACT_ADDRESS_V1,\n MAX_FIELD_VALUE,\n },\n contract_class_id::ContractClassId,\n hash::{poseidon2_hash_with_separator, private_functions_root_from_siblings},\n merkle_tree::membership::MembershipWitness,\n public_keys::{IvpkM, NpkM, OvpkM, PublicKeys, ToPoint, TpkM},\n traits::{Deserialize, Empty, FromField, Packable, Serialize, ToField},\n};\n\n// We do below because `use crate::point::Point;` does not work\nuse dep::std::embedded_curve_ops::EmbeddedCurvePoint as Point;\n\nuse crate::public_keys::AddressPoint;\nuse ec::{pow, sqrt};\nuse std::{\n embedded_curve_ops::{EmbeddedCurveScalar, fixed_base_scalar_mul as derive_public_key},\n ops::Add,\n};\n\n// Aztec address\npub struct AztecAddress {\n pub inner: Field,\n}\n\nimpl Eq for AztecAddress {\n fn eq(self, other: Self) -> bool {\n self.to_field() == other.to_field()\n }\n}\n\nimpl Empty for AztecAddress {\n fn empty() -> Self {\n Self { inner: 0 }\n }\n}\n\nimpl ToField for AztecAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl FromField for AztecAddress {\n fn from_field(value: Field) -> AztecAddress {\n AztecAddress { inner: value }\n }\n}\n\nimpl Serialize for AztecAddress {\n fn serialize(self: Self) -> [Field; AZTEC_ADDRESS_LENGTH] {\n [self.to_field()]\n }\n}\n\nimpl Deserialize for AztecAddress {\n fn deserialize(fields: [Field; AZTEC_ADDRESS_LENGTH]) -> Self {\n FromField::from_field(fields[0])\n }\n}\n\n/// We implement the Packable trait for AztecAddress because it can be stored in contract's storage (and there\n/// the implementation of Packable is required).\nimpl Packable for AztecAddress {\n fn pack(self) -> [Field; AZTEC_ADDRESS_LENGTH] {\n self.serialize()\n }\n\n fn unpack(fields: [Field; AZTEC_ADDRESS_LENGTH]) -> Self {\n Self::deserialize(fields)\n }\n}\n\nimpl AztecAddress {\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n\n pub fn to_address_point(self) -> AddressPoint {\n // We compute the address point by taking our address, setting it to x, and then solving for y in the\n // equation which defines our bn curve:\n // y^2 = x^3 - 17; x = address\n let x = self.inner;\n let y_squared = pow(x, 3) - 17;\n\n // TODO (#8970): Handle cases where we cannot recover a point from an address\n let mut y = sqrt(y_squared);\n\n // If we get a negative y coordinate (any y where y > MAX_FIELD_VALUE / 2), we pin it to the\n // positive one (any value where y <= MAX_FIELD_VALUE / 2) by subtracting it from the Field modulus\n // note: The field modulus is MAX_FIELD_VALUE + 1\n if (!(y.lt(MAX_FIELD_VALUE / 2) | y.eq(MAX_FIELD_VALUE / 2))) {\n y = (MAX_FIELD_VALUE + 1) - y;\n }\n\n AddressPoint { inner: Point { x: self.inner, y, is_infinite: false } }\n }\n\n pub fn compute(public_keys: PublicKeys, partial_address: PartialAddress) -> AztecAddress {\n let public_keys_hash = public_keys.hash();\n\n let pre_address = poseidon2_hash_with_separator(\n [public_keys_hash.to_field(), partial_address.to_field()],\n GENERATOR_INDEX__CONTRACT_ADDRESS_V1,\n );\n\n let address_point = derive_public_key(EmbeddedCurveScalar::from_field(pre_address)).add(\n public_keys.ivpk_m.to_point(),\n );\n\n // Note that our address is only the x-coordinate of the full address_point. This is okay because when people want to encrypt something and send it to us\n // they can recover our full point using the x-coordinate (our address itself). To do this, they recompute the y-coordinate according to the equation y^2 = x^3 - 17.\n // When they do this, they may get a positive y-coordinate (a value that is less than or equal to MAX_FIELD_VALUE / 2) or\n // a negative y-coordinate (a value that is more than MAX_FIELD_VALUE), and we cannot dictate which one they get and hence the recovered point may sometimes be different than the one\n // our secrect can decrypt. Regardless though, they should and will always encrypt using point with the positive y-coordinate by convention.\n // This ensures that everyone encrypts to the same point given an arbitrary x-coordinate (address). This is allowed because even though our original point may not have a positive y-coordinate,\n // with our original secret, we will be able to derive the secret to the point with the flipped (and now positive) y-coordinate that everyone encrypts to.\n AztecAddress::from_field(address_point.x)\n }\n\n pub fn compute_from_private_function(\n function_selector: FunctionSelector,\n function_vk_hash: Field,\n function_leaf_membership_witness: MembershipWitness,\n contract_class_artifact_hash: Field,\n contract_class_public_bytecode_commitment: Field,\n salted_initialization_hash: SaltedInitializationHash,\n public_keys: PublicKeys,\n ) -> Self {\n let private_functions_root = private_functions_root_from_siblings(\n function_selector,\n function_vk_hash,\n function_leaf_membership_witness.leaf_index,\n function_leaf_membership_witness.sibling_path,\n );\n\n let contract_class_id = ContractClassId::compute(\n contract_class_artifact_hash,\n private_functions_root,\n contract_class_public_bytecode_commitment,\n );\n\n // Compute contract address using the preimage which includes the class_id.\n let partial_address = PartialAddress::compute_from_salted_initialization_hash(\n contract_class_id,\n salted_initialization_hash,\n );\n\n AztecAddress::compute(public_keys, partial_address)\n }\n\n pub fn is_zero(self) -> bool {\n self.inner == 0\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\n#[test]\nfn compute_address_from_partial_and_pub_keys() {\n let public_keys = PublicKeys {\n npk_m: NpkM {\n inner: Point {\n x: 0x22f7fcddfa3ce3e8f0cc8e82d7b94cdd740afa3e77f8e4a63ea78a239432dcab,\n y: 0x0471657de2b6216ade6c506d28fbc22ba8b8ed95c871ad9f3e3984e90d9723a7,\n is_infinite: false,\n },\n },\n ivpk_m: IvpkM {\n inner: Point {\n x: 0x111223493147f6785514b1c195bb37a2589f22a6596d30bb2bb145fdc9ca8f1e,\n y: 0x273bbffd678edce8fe30e0deafc4f66d58357c06fd4a820285294b9746c3be95,\n is_infinite: false,\n },\n },\n ovpk_m: OvpkM {\n inner: Point {\n x: 0x09115c96e962322ffed6522f57194627136b8d03ac7469109707f5e44190c484,\n y: 0x0c49773308a13d740a7f0d4f0e6163b02c5a408b6f965856b6a491002d073d5b,\n is_infinite: false,\n },\n },\n tpk_m: TpkM {\n inner: Point {\n x: 0x00d3d81beb009873eb7116327cf47c612d5758ef083d4fda78e9b63980b2a762,\n y: 0x2f567d22d2b02fe1f4ad42db9d58a36afd1983e7e2909d1cab61cafedad6193a,\n is_infinite: false,\n },\n },\n };\n\n let partial_address = PartialAddress::from_field(\n 0x0a7c585381b10f4666044266a02405bf6e01fa564c8517d4ad5823493abd31de,\n );\n\n let address = AztecAddress::compute(public_keys, partial_address);\n\n // The following value was generated by `derivation.test.ts`.\n // --> Run the test with AZTEC_GENERATE_TEST_DATA=1 flag to update test data.\n let expected_computed_address_from_partial_and_pubkeys =\n 0x24e4646f58b9fbe7d38e317db8d5636c423fbbdfbe119fc190fe9c64747e0c62;\n assert(address.to_field() == expected_computed_address_from_partial_and_pubkeys);\n}\n\n#[test]\nfn compute_preaddress_from_partial_and_pub_keys() {\n let pre_address = poseidon2_hash_with_separator([1, 2], GENERATOR_INDEX__CONTRACT_ADDRESS_V1);\n let expected_computed_preaddress_from_partial_and_pubkey =\n 0x23ce9be3fa3c846b0f9245cc796902e731d04f086e8a42473bb29e405fc98075;\n assert(pre_address == expected_computed_preaddress_from_partial_and_pubkey);\n}\n\n#[test]\nfn from_field_to_field() {\n let address = AztecAddress { inner: 37 };\n assert_eq(FromField::from_field(address.to_field()), address);\n}\n\n#[test]\nfn serde() {\n let address = AztecAddress { inner: 37 };\n assert_eq(Deserialize::deserialize(address.serialize()), address);\n}\n" }, - "250": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr", - "source": "use crate::{\n abis::{\n contract_class_function_leaf_preimage::ContractClassFunctionLeafPreimage,\n function_selector::FunctionSelector,\n log_hash::{LogHash, ScopedLogHash},\n note_hash::ScopedNoteHash,\n nullifier::ScopedNullifier,\n private_log::{PrivateLog, PrivateLogData},\n side_effect::{OrderedValue, scoped::Scoped},\n },\n address::{AztecAddress, EthAddress},\n constants::{\n FUNCTION_TREE_HEIGHT, GENERATOR_INDEX__NOTE_HASH_NONCE, GENERATOR_INDEX__OUTER_NULLIFIER,\n GENERATOR_INDEX__SILOED_NOTE_HASH, GENERATOR_INDEX__UNIQUE_NOTE_HASH,\n },\n merkle_tree::root::root_from_sibling_path,\n messaging::l2_to_l1_message::{L2ToL1Message, ScopedL2ToL1Message},\n poseidon2::Poseidon2Sponge,\n traits::{FromField, Hash, is_empty, ToField},\n utils::field::field_from_bytes_32_trunc,\n};\nuse super::{constants::TWO_POW_64, utils::{arrays::array_concat, field::field_from_bytes}};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = std::hash::sha256(bytes_to_hash);\n let hash_in_a_field = field_from_bytes_32_trunc(sha256_hashed);\n\n hash_in_a_field\n}\n\npub fn private_functions_root_from_siblings(\n selector: FunctionSelector,\n vk_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT],\n) -> Field {\n let function_leaf_preimage = ContractClassFunctionLeafPreimage { selector, vk_hash };\n let function_leaf = function_leaf_preimage.hash();\n root_from_sibling_path(\n function_leaf,\n function_leaf_index,\n function_leaf_sibling_path,\n )\n}\n\npub fn compute_note_hash_nonce(first_nullifier_in_tx: Field, note_index_in_tx: u32) -> Field {\n // Hashing the first nullifier with note index in tx is guaranteed to be unique (because all nullifiers are also\n // unique).\n poseidon2_hash_with_separator(\n [first_nullifier_in_tx, note_index_in_tx as Field],\n GENERATOR_INDEX__NOTE_HASH_NONCE,\n )\n}\n\npub fn compute_unique_note_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n let inputs = [nonce, siloed_note_hash];\n poseidon2_hash_with_separator(inputs, GENERATOR_INDEX__UNIQUE_NOTE_HASH)\n}\n\npub fn compute_siloed_note_hash(app: AztecAddress, note_hash: Field) -> Field {\n poseidon2_hash_with_separator(\n [app.to_field(), note_hash],\n GENERATOR_INDEX__SILOED_NOTE_HASH,\n )\n}\n\n/// Computes unique note hashes from siloed note hashes\npub fn compute_unique_siloed_note_hash(\n siloed_note_hash: Field,\n first_nullifier: Field,\n note_index_in_tx: u32,\n) -> Field {\n if siloed_note_hash == 0 {\n 0\n } else {\n let nonce = compute_note_hash_nonce(first_nullifier, note_index_in_tx);\n compute_unique_note_hash(nonce, siloed_note_hash)\n }\n}\n\n/// Siloing in the context of Aztec refers to the process of hashing a note hash with a contract address (this way\n/// the note hash is scoped to a specific contract). This is used to prevent intermingling of notes between contracts.\npub fn silo_note_hash(note_hash: ScopedNoteHash) -> Field {\n if note_hash.contract_address.is_zero() {\n 0\n } else {\n compute_siloed_note_hash(note_hash.contract_address, note_hash.value())\n }\n}\n\npub fn compute_siloed_nullifier(app: AztecAddress, nullifier: Field) -> Field {\n poseidon2_hash_with_separator(\n [app.to_field(), nullifier],\n GENERATOR_INDEX__OUTER_NULLIFIER,\n )\n}\n\npub fn silo_nullifier(nullifier: ScopedNullifier) -> Field {\n if nullifier.contract_address.is_zero() {\n nullifier.value() // Return value instead of 0 because the first nullifier's contract address is zero.\n } else {\n compute_siloed_nullifier(nullifier.contract_address, nullifier.value())\n }\n}\n\npub fn compute_siloed_private_log_field(contract_address: AztecAddress, field: Field) -> Field {\n poseidon2_hash([contract_address.to_field(), field])\n}\n\npub fn silo_private_log(private_log: Scoped) -> PrivateLog {\n if private_log.contract_address.is_zero() {\n private_log.inner.log\n } else {\n let mut fields = private_log.inner.log.fields;\n fields[0] = compute_siloed_private_log_field(private_log.contract_address, fields[0]);\n PrivateLog { fields }\n }\n}\n\nfn compute_siloed_unencrypted_log_hash(address: AztecAddress, log_hash: Field) -> Field {\n accumulate_sha256([address.to_field(), log_hash])\n}\n\npub fn silo_unencrypted_log_hash(log_hash: ScopedLogHash) -> Field {\n if log_hash.contract_address.is_zero() {\n 0\n } else {\n compute_siloed_unencrypted_log_hash(log_hash.contract_address, log_hash.value())\n }\n}\n\npub fn merkle_hash(left: Field, right: Field) -> Field {\n poseidon2_hash([left, right])\n}\n\npub fn compute_l2_to_l1_hash(\n contract_address: AztecAddress,\n recipient: EthAddress,\n content: Field,\n rollup_version_id: Field,\n chain_id: Field,\n) -> Field {\n let mut bytes: [u8; 160] = std::mem::zeroed();\n\n let inputs =\n [contract_address.to_field(), rollup_version_id, recipient.to_field(), chain_id, content];\n for i in 0..5 {\n // TODO are bytes be in fr.to_buffer() ?\n let item_bytes: [u8; 32] = inputs[i].to_be_bytes();\n for j in 0..32 {\n bytes[32 * i + j] = item_bytes[j];\n }\n }\n\n sha256_to_field(bytes)\n}\n\npub fn silo_l2_to_l1_message(\n msg: ScopedL2ToL1Message,\n rollup_version_id: Field,\n chain_id: Field,\n) -> Field {\n if msg.contract_address.is_zero() {\n 0\n } else {\n compute_l2_to_l1_hash(\n msg.contract_address,\n msg.message.recipient,\n msg.message.content,\n rollup_version_id,\n chain_id,\n )\n }\n}\n\n// Computes sha256 hash of 2 input hashes.\n//\n// NB: This method now takes in two 31 byte fields - it assumes that any input\n// is the result of a sha_to_field hash and => is truncated\n//\n// TODO(Jan and David): This is used for the encrypted_log hashes.\n// Can we check to see if we can just use hash_to_field or pedersen_compress here?\n//\npub fn accumulate_sha256(input: [Field; 2]) -> Field {\n // This is a note about the cpp code, since it takes an array of Fields\n // instead of a U128.\n // 4 Field elements when converted to bytes will usually\n // occupy 4 * 32 = 128 bytes.\n // However, this function is making the assumption that each Field\n // only occupies 128 bits.\n //\n // TODO(David): This does not seem to be getting guaranteed anywhere in the code?\n // Concatentate two fields into 32x2 = 64 bytes\n // accumulate_sha256 assumes that the inputs are pre-truncated 31 byte numbers\n let mut hash_input_flattened = [0; 64];\n for offset in 0..input.len() {\n let input_as_bytes: [u8; 32] = input[offset].to_be_bytes();\n for byte_index in 0..32 {\n hash_input_flattened[offset * 32 + byte_index] = input_as_bytes[byte_index];\n }\n }\n\n sha256_to_field(hash_input_flattened)\n}\n\n// Computes the final logs hash for a tx.\npub fn compute_tx_logs_hash(logs: [LogHash; N]) -> Field {\n // Convert each field element into a byte array and append the bytes to `hash_input_flattened`\n let mut hash_input_flattened = [0; N * 32];\n for offset in 0..N {\n // TODO: This is not checking that the decomposition is smaller than P\n let input_as_bytes: [u8; 32] = logs[offset].value.to_be_radix(256);\n for byte_index in 0..32 {\n hash_input_flattened[offset * 32 + byte_index] = input_as_bytes[byte_index];\n }\n }\n // Ideally we would push to a slice then hash, but there is no sha_slice\n // Hardcode to 256 bytes for now\n let mut hash = sha256_to_field(hash_input_flattened);\n // Not having a 0 value hash for empty logs causes issues with empty txs\n // used for padding. Returning early is currently unsupported.\n // We always provide sorted logs here, so 0 being empty means all are empty.\n if is_empty(logs[0]) {\n hash = 0;\n }\n hash\n}\n\npub fn verification_key_hash(key: [Field; N]) -> Field {\n crate::hash::poseidon2_hash(key)\n}\n\n#[inline_always]\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n std::hash::pedersen_hash_with_separator(inputs, hash_index)\n}\n\npub fn poseidon2_hash(inputs: [Field; N]) -> Field {\n std::hash::poseidon2::Poseidon2::hash(inputs, N)\n}\n\n#[no_predicates]\npub fn poseidon2_hash_with_separator(inputs: [Field; N], separator: T) -> Field\nwhere\n T: ToField,\n{\n let inputs_with_separator = array_concat([separator.to_field()], inputs);\n poseidon2_hash(inputs_with_separator)\n}\n\n// Performs a fixed length hash with a subarray of the given input.\n// Useful for SpongeBlob in which we aborb M things and want to check it vs a hash of M elts of an N-len array.\n// Using stdlib poseidon, this will always absorb an extra 1 as a 'variable' hash, and not match spongeblob.squeeze()\n// or any ts implementation. Also checks that any remaining elts not hashed are empty.\n#[no_predicates]\npub fn poseidon2_hash_subarray(input: [Field; N], in_len: u32) -> Field {\n let mut sponge = poseidon2_absorb_chunks(input, in_len, false);\n sponge.squeeze()\n}\n\n// NB the below is the same as std::hash::poseidon2::Poseidon2::hash(), but replacing a range check with a bit check,\n// and absorbing in chunks of 3 below.\n#[no_predicates]\npub fn poseidon2_cheaper_variable_hash(input: [Field; N], in_len: u32) -> Field {\n let mut sponge = poseidon2_absorb_chunks(input, in_len, true);\n // In the case where the hash preimage is variable-length, we append `1` to the end of the input, to distinguish\n // from fixed-length hashes. (the combination of this additional field element + the hash IV ensures\n // fixed-length and variable-length hashes do not collide)\n if in_len != N {\n sponge.absorb(1);\n }\n sponge.squeeze()\n}\n\n// The below fn reduces gates of a conditional poseidon2 hash by approx 3x (thank you ~* Giant Brain Dev @IlyasRidhuan *~ for the idea)\n// Why? Because when we call stdlib poseidon, we call absorb for each item. When absorbing is conditional, it seems the compiler does not know\n// what cache_size will be when calling absorb, so it assigns the permutation gates for /each i/ rather than /every 3rd i/, which is actually required.\n// The below code forces the compiler to:\n// - absorb normally up to 2 times to set cache_size to 1\n// - absorb in chunks of 3 to ensure perm. only happens every 3rd absorb\n// - absorb normally up to 2 times to add any remaining values to the hash\n// In fixed len hashes, the compiler is able to tell that it will only need to perform the permutation every 3 absorbs.\n// NB: it also replaces unnecessary range checks (i < thing) with a bit check (&= i != thing), which alone reduces the gates of a var. hash by half.\n\n#[no_predicates]\nfn poseidon2_absorb_chunks(\n input: [Field; N],\n in_len: u32,\n variable: bool,\n) -> Poseidon2Sponge {\n let iv: Field = (in_len as Field) * TWO_POW_64;\n let mut sponge = Poseidon2Sponge::new(iv);\n // Even though shift is always 1 here, if we input in_len = 0 we get an underflow\n // since we cannot isolate computation branches. The below is just to avoid that.\n let shift = if in_len == 0 { 0 } else { 1 };\n if in_len != 0 {\n // cache_size = 0, init absorb\n sponge.cache[0] = input[0];\n sponge.cache_size = 1;\n // shift = num elts already added to make cache_size 1 = 1 for a fresh sponge\n // M = max_chunks = (N - 1 - (N - 1) % 3) / 3: (must be written as a fn of N to compile)\n // max_remainder = (N - 1) % 3;\n // max_chunks = (N - 1 - max_remainder) / 3;\n sponge = poseidon2_absorb_chunks_loop::(\n sponge,\n input,\n in_len,\n variable,\n shift,\n );\n }\n sponge\n}\n\n// NB: If it's not required to check that the non-absorbed elts of 'input' are 0s, set skip_0_check=true\n#[no_predicates]\npub fn poseidon2_absorb_chunks_existing_sponge(\n in_sponge: Poseidon2Sponge,\n input: [Field; N],\n in_len: u32,\n skip_0_check: bool,\n) -> Poseidon2Sponge {\n let mut sponge = in_sponge;\n // 'shift' is to account for already added inputs\n let mut shift = 0;\n // 'stop' is to avoid an underflow when inputting in_len = 0\n let mut stop = false;\n for i in 0..3 {\n if shift == in_len {\n stop = true;\n }\n if (sponge.cache_size != 1) & (!stop) {\n sponge.absorb(input[i]);\n shift += 1;\n }\n }\n sponge = if stop {\n sponge\n } else {\n // max_chunks = (N - (N % 3)) / 3;\n poseidon2_absorb_chunks_loop::(\n sponge,\n input,\n in_len,\n skip_0_check,\n shift,\n )\n };\n sponge\n}\n\n// The below is the loop to absorb elts into a poseidon sponge in chunks of 3\n// shift - the num of elts already absorbed to ensure the sponge's cache_size = 1\n// M - the max number of chunks required to absorb N things (must be comptime to compile)\n// NB: The 0 checks ('Found non-zero field...') are messy, but having a separate loop over N to check\n// for 0s costs 3N gates. Current approach is approx 2N gates.\n#[no_predicates]\nfn poseidon2_absorb_chunks_loop(\n in_sponge: Poseidon2Sponge,\n input: [Field; N],\n in_len: u32,\n variable: bool,\n shift: u32,\n) -> Poseidon2Sponge {\n assert(in_len <= N, \"Given in_len to absorb is larger than the input array len\");\n // When we have an existing sponge, we may have a shift of 0, and the final 'k+2' below = N\n // The below avoids an overflow\n let skip_last = 3 * M == N;\n // Writing in_sponge: &mut does not compile\n let mut sponge = in_sponge;\n let mut should_add = true;\n // The num of things left over after absorbing in 3s\n let remainder = (in_len - shift) % 3;\n // The num of chunks of 3 to absorb (maximum M)\n let chunks = (in_len - shift - remainder) / 3;\n for i in 0..M {\n // Now we loop through cache size = 1 -> 3\n should_add &= i != chunks;\n // This is the index at the start of the chunk (for readability)\n let k = 3 * i + shift;\n if should_add {\n // cache_size = 1, 2 => just assign\n sponge.cache[1] = input[k];\n sponge.cache[2] = input[k + 1];\n // cache_size = 3 => duplex + perm\n for j in 0..3 {\n sponge.state[j] += sponge.cache[j];\n }\n sponge.state = std::hash::poseidon2_permutation(sponge.state, 4);\n sponge.cache[0] = input[k + 2];\n // cache_size is now 1 again, repeat loop\n } else if (!variable) & (i != chunks) {\n // if we are hashing a fixed len array which is a subarray, we check the remaining elts are 0\n // NB: we don't check at i == chunks, because that chunk contains elts to be absorbed or checked below\n let last_0 = if (i == M - 1) & (skip_last) {\n 0\n } else {\n input[k + 2]\n };\n let all_0 = (input[k] == 0) & (input[k + 1] == 0) & (last_0 == 0);\n assert(all_0, \"Found non-zero field after breakpoint\");\n }\n }\n // we have 'remainder' num of items left to absorb\n should_add = true;\n // below is to avoid overflows (i.e. if inlen is close to N)\n let mut should_check = !variable;\n for i in 0..3 {\n should_add &= i != remainder;\n should_check &= in_len - remainder + i != N;\n if should_add {\n // we want to absorb the final 'remainder' items\n sponge.absorb(input[in_len - remainder + i]);\n } else if should_check {\n assert(input[in_len - remainder + i] == 0, \"Found non-zero field after breakpoint\");\n }\n }\n sponge\n}\n\npub fn poseidon2_hash_with_separator_slice(inputs: [Field], separator: T) -> Field\nwhere\n T: ToField,\n{\n let in_len = inputs.len() + 1;\n let iv: Field = (in_len as Field) * TWO_POW_64;\n let mut sponge = Poseidon2Sponge::new(iv);\n sponge.absorb(separator.to_field());\n\n for i in 0..inputs.len() {\n sponge.absorb(inputs[i]);\n }\n\n sponge.squeeze()\n}\n\n#[no_predicates]\npub fn poseidon2_hash_bytes(inputs: [u8; N]) -> Field {\n let mut fields = [0; (N + 30) / 31];\n let mut field_index = 0;\n let mut current_field = [0; 31];\n for i in 0..inputs.len() {\n let index = i % 31;\n current_field[index] = inputs[i];\n if index == 30 {\n fields[field_index] = field_from_bytes(current_field, false);\n current_field = [0; 31];\n field_index += 1;\n }\n }\n if field_index != fields.len() {\n fields[field_index] = field_from_bytes(current_field, false);\n }\n poseidon2_hash(fields)\n}\n\n#[test]\nfn poseidon_chunks_matches_fixed() {\n let in_len = 501;\n let mut input: [Field; 4096] = [0; 4096];\n let mut fixed_input = [3; 501];\n assert(in_len == fixed_input.len()); // sanity check\n for i in 0..in_len {\n input[i] = 3;\n }\n let sub_chunk_hash = poseidon2_hash_subarray(input, in_len);\n let fixed_len_hash = std::hash::poseidon2::Poseidon2::hash(fixed_input, fixed_input.len());\n assert(sub_chunk_hash == fixed_len_hash);\n}\n\n#[test]\nfn poseidon_chunks_matches_variable() {\n let in_len = 501;\n let mut input: [Field; 4096] = [0; 4096];\n for i in 0..in_len {\n input[i] = 3;\n }\n let variable_chunk_hash = poseidon2_cheaper_variable_hash(input, in_len);\n let variable_len_hash = std::hash::poseidon2::Poseidon2::hash(input, in_len);\n assert(variable_chunk_hash == variable_len_hash);\n}\n\n#[test]\nfn existing_sponge_poseidon_chunks_matches_fixed() {\n let in_len = 501;\n let mut input: [Field; 4096] = [0; 4096];\n let mut fixed_input = [3; 501];\n assert(in_len == fixed_input.len()); // sanity check\n for i in 0..in_len {\n input[i] = 3;\n }\n // absorb 250 of the 501 things\n let empty_sponge = Poseidon2Sponge::new((in_len as Field) * TWO_POW_64);\n let first_sponge = poseidon2_absorb_chunks_existing_sponge(empty_sponge, input, 250, true);\n // now absorb the final 251 (since they are all 3s, im being lazy and not making a new array)\n let mut final_sponge = poseidon2_absorb_chunks_existing_sponge(first_sponge, input, 251, true);\n let fixed_len_hash = Poseidon2Sponge::hash(fixed_input, fixed_input.len());\n assert(final_sponge.squeeze() == fixed_len_hash);\n}\n\n#[test]\nfn poseidon_chunks_empty_inputs() {\n let in_len = 0;\n let mut input: [Field; 4096] = [0; 4096];\n let mut contructed_empty_sponge = poseidon2_absorb_chunks(input, in_len, true);\n let mut first_sponge =\n poseidon2_absorb_chunks_existing_sponge(contructed_empty_sponge, input, in_len, true);\n assert(first_sponge.squeeze() == contructed_empty_sponge.squeeze());\n}\n\n#[test]\nfn smoke_sha256_to_field() {\n let full_buffer = [\n 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,\n 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,\n 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,\n 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,\n 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,\n 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,\n 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,\n ];\n let result = sha256_to_field(full_buffer);\n\n assert(result == 0x448ebbc9e1a31220a2f3830c18eef61b9bd070e5084b7fa2a359fe729184c7);\n\n // to show correctness of the current ver (truncate one byte) vs old ver (mod full bytes):\n let result_bytes = std::hash::sha256(full_buffer);\n let truncated_field = crate::utils::field::field_from_bytes_32_trunc(result_bytes);\n assert(truncated_field == result);\n let mod_res = result + (result_bytes[31] as Field);\n assert(mod_res == 0x448ebbc9e1a31220a2f3830c18eef61b9bd070e5084b7fa2a359fe729184e0);\n}\n\n#[test]\nfn compute_l2_l1_hash() {\n // All zeroes\n let hash_result =\n compute_l2_to_l1_hash(AztecAddress::from_field(0), EthAddress::zero(), 0, 0, 0);\n assert(hash_result == 0xb393978842a0fa3d3e1470196f098f473f9678e72463cb65ec4ab5581856c2);\n\n // Non-zero case\n let hash_result = compute_l2_to_l1_hash(\n AztecAddress::from_field(1),\n EthAddress::from_field(3),\n 5,\n 2,\n 4,\n );\n assert(hash_result == 0x3f88c1044a05e5340ed20466276500f6d45ca5603913b9091e957161734e16);\n}\n\n#[test]\nfn silo_l2_to_l1_message_matches_typescript() {\n let version = 4;\n let chainId = 5;\n\n let hash = silo_l2_to_l1_message(\n ScopedL2ToL1Message {\n message: L2ToL1Message { recipient: EthAddress::from_field(1), content: 2, counter: 0 },\n contract_address: AztecAddress::from_field(3),\n },\n version,\n chainId,\n );\n\n // The following value was generated by `l2_to_l1_message.test.ts`\n let hash_from_typescript = 0x00c6155d69febb9d5039b374dd4f77bf57b7c881709aa524a18acaa0bd57476a;\n\n assert_eq(hash, hash_from_typescript);\n}\n" + "251": { + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr", + "source": "use crate::{\n abis::{\n contract_class_function_leaf_preimage::ContractClassFunctionLeafPreimage,\n function_selector::FunctionSelector,\n log_hash::{LogHash, ScopedLogHash},\n note_hash::ScopedNoteHash,\n nullifier::ScopedNullifier,\n private_log::{PrivateLog, PrivateLogData},\n side_effect::{OrderedValue, scoped::Scoped},\n },\n address::{AztecAddress, EthAddress},\n constants::{\n FUNCTION_TREE_HEIGHT, GENERATOR_INDEX__NOTE_HASH_NONCE, GENERATOR_INDEX__OUTER_NULLIFIER,\n GENERATOR_INDEX__SILOED_NOTE_HASH, GENERATOR_INDEX__UNIQUE_NOTE_HASH,\n },\n merkle_tree::root::root_from_sibling_path,\n messaging::l2_to_l1_message::{L2ToL1Message, ScopedL2ToL1Message},\n poseidon2::Poseidon2Sponge,\n traits::{FromField, Hash, is_empty, ToField},\n utils::field::field_from_bytes_32_trunc,\n};\nuse super::{constants::TWO_POW_64, utils::{arrays::array_concat, field::field_from_bytes}};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = std::hash::sha256(bytes_to_hash);\n let hash_in_a_field = field_from_bytes_32_trunc(sha256_hashed);\n\n hash_in_a_field\n}\n\npub fn private_functions_root_from_siblings(\n selector: FunctionSelector,\n vk_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT],\n) -> Field {\n let function_leaf_preimage = ContractClassFunctionLeafPreimage { selector, vk_hash };\n let function_leaf = function_leaf_preimage.hash();\n root_from_sibling_path(\n function_leaf,\n function_leaf_index,\n function_leaf_sibling_path,\n )\n}\n\npub fn compute_note_hash_nonce(first_nullifier_in_tx: Field, note_index_in_tx: u32) -> Field {\n // Hashing the first nullifier with note index in tx is guaranteed to be unique (because all nullifiers are also\n // unique).\n poseidon2_hash_with_separator(\n [first_nullifier_in_tx, note_index_in_tx as Field],\n GENERATOR_INDEX__NOTE_HASH_NONCE,\n )\n}\n\npub fn compute_unique_note_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n let inputs = [nonce, siloed_note_hash];\n poseidon2_hash_with_separator(inputs, GENERATOR_INDEX__UNIQUE_NOTE_HASH)\n}\n\npub fn compute_siloed_note_hash(app: AztecAddress, note_hash: Field) -> Field {\n poseidon2_hash_with_separator(\n [app.to_field(), note_hash],\n GENERATOR_INDEX__SILOED_NOTE_HASH,\n )\n}\n\n/// Computes unique note hashes from siloed note hashes\npub fn compute_unique_siloed_note_hash(\n siloed_note_hash: Field,\n first_nullifier: Field,\n note_index_in_tx: u32,\n) -> Field {\n if siloed_note_hash == 0 {\n 0\n } else {\n let nonce = compute_note_hash_nonce(first_nullifier, note_index_in_tx);\n compute_unique_note_hash(nonce, siloed_note_hash)\n }\n}\n\n/// Siloing in the context of Aztec refers to the process of hashing a note hash with a contract address (this way\n/// the note hash is scoped to a specific contract). This is used to prevent intermingling of notes between contracts.\npub fn silo_note_hash(note_hash: ScopedNoteHash) -> Field {\n if note_hash.contract_address.is_zero() {\n 0\n } else {\n compute_siloed_note_hash(note_hash.contract_address, note_hash.value())\n }\n}\n\npub fn compute_siloed_nullifier(app: AztecAddress, nullifier: Field) -> Field {\n poseidon2_hash_with_separator(\n [app.to_field(), nullifier],\n GENERATOR_INDEX__OUTER_NULLIFIER,\n )\n}\n\npub fn silo_nullifier(nullifier: ScopedNullifier) -> Field {\n if nullifier.contract_address.is_zero() {\n nullifier.value() // Return value instead of 0 because the first nullifier's contract address is zero.\n } else {\n compute_siloed_nullifier(nullifier.contract_address, nullifier.value())\n }\n}\n\npub fn compute_siloed_private_log_field(contract_address: AztecAddress, field: Field) -> Field {\n poseidon2_hash([contract_address.to_field(), field])\n}\n\npub fn silo_private_log(private_log: Scoped) -> PrivateLog {\n if private_log.contract_address.is_zero() {\n private_log.inner.log\n } else {\n let mut fields = private_log.inner.log.fields;\n fields[0] = compute_siloed_private_log_field(private_log.contract_address, fields[0]);\n PrivateLog { fields }\n }\n}\n\nfn compute_siloed_contract_class_log_hash(address: AztecAddress, log_hash: Field) -> Field {\n accumulate_sha256([address.to_field(), log_hash])\n}\n\npub fn silo_contract_class_log_hash(log_hash: ScopedLogHash) -> Field {\n if log_hash.contract_address.is_zero() {\n 0\n } else {\n compute_siloed_contract_class_log_hash(log_hash.contract_address, log_hash.value())\n }\n}\n\npub fn merkle_hash(left: Field, right: Field) -> Field {\n poseidon2_hash([left, right])\n}\n\npub fn compute_l2_to_l1_hash(\n contract_address: AztecAddress,\n recipient: EthAddress,\n content: Field,\n rollup_version_id: Field,\n chain_id: Field,\n) -> Field {\n let mut bytes: [u8; 160] = std::mem::zeroed();\n\n let inputs =\n [contract_address.to_field(), rollup_version_id, recipient.to_field(), chain_id, content];\n for i in 0..5 {\n // TODO are bytes be in fr.to_buffer() ?\n let item_bytes: [u8; 32] = inputs[i].to_be_bytes();\n for j in 0..32 {\n bytes[32 * i + j] = item_bytes[j];\n }\n }\n\n sha256_to_field(bytes)\n}\n\npub fn silo_l2_to_l1_message(\n msg: ScopedL2ToL1Message,\n rollup_version_id: Field,\n chain_id: Field,\n) -> Field {\n if msg.contract_address.is_zero() {\n 0\n } else {\n compute_l2_to_l1_hash(\n msg.contract_address,\n msg.message.recipient,\n msg.message.content,\n rollup_version_id,\n chain_id,\n )\n }\n}\n\n// Computes sha256 hash of 2 input hashes.\n//\n// NB: This method now takes in two 31 byte fields - it assumes that any input\n// is the result of a sha_to_field hash and => is truncated\n//\n// TODO(Jan and David): This is used for the encrypted_log hashes.\n// Can we check to see if we can just use hash_to_field or pedersen_compress here?\n//\npub fn accumulate_sha256(input: [Field; 2]) -> Field {\n // This is a note about the cpp code, since it takes an array of Fields\n // instead of a U128.\n // 4 Field elements when converted to bytes will usually\n // occupy 4 * 32 = 128 bytes.\n // However, this function is making the assumption that each Field\n // only occupies 128 bits.\n //\n // TODO(David): This does not seem to be getting guaranteed anywhere in the code?\n // Concatentate two fields into 32x2 = 64 bytes\n // accumulate_sha256 assumes that the inputs are pre-truncated 31 byte numbers\n let mut hash_input_flattened = [0; 64];\n for offset in 0..input.len() {\n let input_as_bytes: [u8; 32] = input[offset].to_be_bytes();\n for byte_index in 0..32 {\n hash_input_flattened[offset * 32 + byte_index] = input_as_bytes[byte_index];\n }\n }\n\n sha256_to_field(hash_input_flattened)\n}\n\n// Computes the final logs hash for a tx.\npub fn compute_tx_logs_hash(logs: [LogHash; N]) -> Field {\n // Convert each field element into a byte array and append the bytes to `hash_input_flattened`\n let mut hash_input_flattened = [0; N * 32];\n for offset in 0..N {\n // TODO: This is not checking that the decomposition is smaller than P\n let input_as_bytes: [u8; 32] = logs[offset].value.to_be_radix(256);\n for byte_index in 0..32 {\n hash_input_flattened[offset * 32 + byte_index] = input_as_bytes[byte_index];\n }\n }\n // Ideally we would push to a slice then hash, but there is no sha_slice\n // Hardcode to 256 bytes for now\n let mut hash = sha256_to_field(hash_input_flattened);\n // Not having a 0 value hash for empty logs causes issues with empty txs\n // used for padding. Returning early is currently unsupported.\n // We always provide sorted logs here, so 0 being empty means all are empty.\n if is_empty(logs[0]) {\n hash = 0;\n }\n hash\n}\n\npub fn verification_key_hash(key: [Field; N]) -> Field {\n crate::hash::poseidon2_hash(key)\n}\n\n#[inline_always]\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n std::hash::pedersen_hash_with_separator(inputs, hash_index)\n}\n\npub fn poseidon2_hash(inputs: [Field; N]) -> Field {\n std::hash::poseidon2::Poseidon2::hash(inputs, N)\n}\n\n#[no_predicates]\npub fn poseidon2_hash_with_separator(inputs: [Field; N], separator: T) -> Field\nwhere\n T: ToField,\n{\n let inputs_with_separator = array_concat([separator.to_field()], inputs);\n poseidon2_hash(inputs_with_separator)\n}\n\n// Performs a fixed length hash with a subarray of the given input.\n// Useful for SpongeBlob in which we aborb M things and want to check it vs a hash of M elts of an N-len array.\n// Using stdlib poseidon, this will always absorb an extra 1 as a 'variable' hash, and not match spongeblob.squeeze()\n// or any ts implementation. Also checks that any remaining elts not hashed are empty.\n#[no_predicates]\npub fn poseidon2_hash_subarray(input: [Field; N], in_len: u32) -> Field {\n let mut sponge = poseidon2_absorb_chunks(input, in_len, false);\n sponge.squeeze()\n}\n\n// NB the below is the same as std::hash::poseidon2::Poseidon2::hash(), but replacing a range check with a bit check,\n// and absorbing in chunks of 3 below.\n#[no_predicates]\npub fn poseidon2_cheaper_variable_hash(input: [Field; N], in_len: u32) -> Field {\n let mut sponge = poseidon2_absorb_chunks(input, in_len, true);\n // In the case where the hash preimage is variable-length, we append `1` to the end of the input, to distinguish\n // from fixed-length hashes. (the combination of this additional field element + the hash IV ensures\n // fixed-length and variable-length hashes do not collide)\n if in_len != N {\n sponge.absorb(1);\n }\n sponge.squeeze()\n}\n\n// The below fn reduces gates of a conditional poseidon2 hash by approx 3x (thank you ~* Giant Brain Dev @IlyasRidhuan *~ for the idea)\n// Why? Because when we call stdlib poseidon, we call absorb for each item. When absorbing is conditional, it seems the compiler does not know\n// what cache_size will be when calling absorb, so it assigns the permutation gates for /each i/ rather than /every 3rd i/, which is actually required.\n// The below code forces the compiler to:\n// - absorb normally up to 2 times to set cache_size to 1\n// - absorb in chunks of 3 to ensure perm. only happens every 3rd absorb\n// - absorb normally up to 2 times to add any remaining values to the hash\n// In fixed len hashes, the compiler is able to tell that it will only need to perform the permutation every 3 absorbs.\n// NB: it also replaces unnecessary range checks (i < thing) with a bit check (&= i != thing), which alone reduces the gates of a var. hash by half.\n\n#[no_predicates]\nfn poseidon2_absorb_chunks(\n input: [Field; N],\n in_len: u32,\n variable: bool,\n) -> Poseidon2Sponge {\n let iv: Field = (in_len as Field) * TWO_POW_64;\n let mut sponge = Poseidon2Sponge::new(iv);\n // Even though shift is always 1 here, if we input in_len = 0 we get an underflow\n // since we cannot isolate computation branches. The below is just to avoid that.\n let shift = if in_len == 0 { 0 } else { 1 };\n if in_len != 0 {\n // cache_size = 0, init absorb\n sponge.cache[0] = input[0];\n sponge.cache_size = 1;\n // shift = num elts already added to make cache_size 1 = 1 for a fresh sponge\n // M = max_chunks = (N - 1 - (N - 1) % 3) / 3: (must be written as a fn of N to compile)\n // max_remainder = (N - 1) % 3;\n // max_chunks = (N - 1 - max_remainder) / 3;\n sponge = poseidon2_absorb_chunks_loop::(\n sponge,\n input,\n in_len,\n variable,\n shift,\n );\n }\n sponge\n}\n\n// NB: If it's not required to check that the non-absorbed elts of 'input' are 0s, set skip_0_check=true\n#[no_predicates]\npub fn poseidon2_absorb_chunks_existing_sponge(\n in_sponge: Poseidon2Sponge,\n input: [Field; N],\n in_len: u32,\n skip_0_check: bool,\n) -> Poseidon2Sponge {\n let mut sponge = in_sponge;\n // 'shift' is to account for already added inputs\n let mut shift = 0;\n // 'stop' is to avoid an underflow when inputting in_len = 0\n let mut stop = false;\n for i in 0..3 {\n if shift == in_len {\n stop = true;\n }\n if (sponge.cache_size != 1) & (!stop) {\n sponge.absorb(input[i]);\n shift += 1;\n }\n }\n sponge = if stop {\n sponge\n } else {\n // max_chunks = (N - (N % 3)) / 3;\n poseidon2_absorb_chunks_loop::(\n sponge,\n input,\n in_len,\n skip_0_check,\n shift,\n )\n };\n sponge\n}\n\n// The below is the loop to absorb elts into a poseidon sponge in chunks of 3\n// shift - the num of elts already absorbed to ensure the sponge's cache_size = 1\n// M - the max number of chunks required to absorb N things (must be comptime to compile)\n// NB: The 0 checks ('Found non-zero field...') are messy, but having a separate loop over N to check\n// for 0s costs 3N gates. Current approach is approx 2N gates.\n#[no_predicates]\nfn poseidon2_absorb_chunks_loop(\n in_sponge: Poseidon2Sponge,\n input: [Field; N],\n in_len: u32,\n variable: bool,\n shift: u32,\n) -> Poseidon2Sponge {\n assert(in_len <= N, \"Given in_len to absorb is larger than the input array len\");\n // When we have an existing sponge, we may have a shift of 0, and the final 'k+2' below = N\n // The below avoids an overflow\n let skip_last = 3 * M == N;\n // Writing in_sponge: &mut does not compile\n let mut sponge = in_sponge;\n let mut should_add = true;\n // The num of things left over after absorbing in 3s\n let remainder = (in_len - shift) % 3;\n // The num of chunks of 3 to absorb (maximum M)\n let chunks = (in_len - shift - remainder) / 3;\n for i in 0..M {\n // Now we loop through cache size = 1 -> 3\n should_add &= i != chunks;\n // This is the index at the start of the chunk (for readability)\n let k = 3 * i + shift;\n if should_add {\n // cache_size = 1, 2 => just assign\n sponge.cache[1] = input[k];\n sponge.cache[2] = input[k + 1];\n // cache_size = 3 => duplex + perm\n for j in 0..3 {\n sponge.state[j] += sponge.cache[j];\n }\n sponge.state = std::hash::poseidon2_permutation(sponge.state, 4);\n sponge.cache[0] = input[k + 2];\n // cache_size is now 1 again, repeat loop\n } else if (!variable) & (i != chunks) {\n // if we are hashing a fixed len array which is a subarray, we check the remaining elts are 0\n // NB: we don't check at i == chunks, because that chunk contains elts to be absorbed or checked below\n let last_0 = if (i == M - 1) & (skip_last) {\n 0\n } else {\n input[k + 2]\n };\n let all_0 = (input[k] == 0) & (input[k + 1] == 0) & (last_0 == 0);\n assert(all_0, \"Found non-zero field after breakpoint\");\n }\n }\n // we have 'remainder' num of items left to absorb\n should_add = true;\n // below is to avoid overflows (i.e. if inlen is close to N)\n let mut should_check = !variable;\n for i in 0..3 {\n should_add &= i != remainder;\n should_check &= in_len - remainder + i != N;\n if should_add {\n // we want to absorb the final 'remainder' items\n sponge.absorb(input[in_len - remainder + i]);\n } else if should_check {\n assert(input[in_len - remainder + i] == 0, \"Found non-zero field after breakpoint\");\n }\n }\n sponge\n}\n\npub fn poseidon2_hash_with_separator_slice(inputs: [Field], separator: T) -> Field\nwhere\n T: ToField,\n{\n let in_len = inputs.len() + 1;\n let iv: Field = (in_len as Field) * TWO_POW_64;\n let mut sponge = Poseidon2Sponge::new(iv);\n sponge.absorb(separator.to_field());\n\n for i in 0..inputs.len() {\n sponge.absorb(inputs[i]);\n }\n\n sponge.squeeze()\n}\n\n#[no_predicates]\npub fn poseidon2_hash_bytes(inputs: [u8; N]) -> Field {\n let mut fields = [0; (N + 30) / 31];\n let mut field_index = 0;\n let mut current_field = [0; 31];\n for i in 0..inputs.len() {\n let index = i % 31;\n current_field[index] = inputs[i];\n if index == 30 {\n fields[field_index] = field_from_bytes(current_field, false);\n current_field = [0; 31];\n field_index += 1;\n }\n }\n if field_index != fields.len() {\n fields[field_index] = field_from_bytes(current_field, false);\n }\n poseidon2_hash(fields)\n}\n\n#[test]\nfn poseidon_chunks_matches_fixed() {\n let in_len = 501;\n let mut input: [Field; 4096] = [0; 4096];\n let mut fixed_input = [3; 501];\n assert(in_len == fixed_input.len()); // sanity check\n for i in 0..in_len {\n input[i] = 3;\n }\n let sub_chunk_hash = poseidon2_hash_subarray(input, in_len);\n let fixed_len_hash = std::hash::poseidon2::Poseidon2::hash(fixed_input, fixed_input.len());\n assert(sub_chunk_hash == fixed_len_hash);\n}\n\n#[test]\nfn poseidon_chunks_matches_variable() {\n let in_len = 501;\n let mut input: [Field; 4096] = [0; 4096];\n for i in 0..in_len {\n input[i] = 3;\n }\n let variable_chunk_hash = poseidon2_cheaper_variable_hash(input, in_len);\n let variable_len_hash = std::hash::poseidon2::Poseidon2::hash(input, in_len);\n assert(variable_chunk_hash == variable_len_hash);\n}\n\n#[test]\nfn existing_sponge_poseidon_chunks_matches_fixed() {\n let in_len = 501;\n let mut input: [Field; 4096] = [0; 4096];\n let mut fixed_input = [3; 501];\n assert(in_len == fixed_input.len()); // sanity check\n for i in 0..in_len {\n input[i] = 3;\n }\n // absorb 250 of the 501 things\n let empty_sponge = Poseidon2Sponge::new((in_len as Field) * TWO_POW_64);\n let first_sponge = poseidon2_absorb_chunks_existing_sponge(empty_sponge, input, 250, true);\n // now absorb the final 251 (since they are all 3s, im being lazy and not making a new array)\n let mut final_sponge = poseidon2_absorb_chunks_existing_sponge(first_sponge, input, 251, true);\n let fixed_len_hash = Poseidon2Sponge::hash(fixed_input, fixed_input.len());\n assert(final_sponge.squeeze() == fixed_len_hash);\n}\n\n#[test]\nfn poseidon_chunks_empty_inputs() {\n let in_len = 0;\n let mut input: [Field; 4096] = [0; 4096];\n let mut constructed_empty_sponge = poseidon2_absorb_chunks(input, in_len, true);\n let mut first_sponge =\n poseidon2_absorb_chunks_existing_sponge(constructed_empty_sponge, input, in_len, true);\n assert(first_sponge.squeeze() == constructed_empty_sponge.squeeze());\n}\n\n#[test]\nfn smoke_sha256_to_field() {\n let full_buffer = [\n 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,\n 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,\n 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,\n 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,\n 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,\n 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,\n 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,\n ];\n let result = sha256_to_field(full_buffer);\n\n assert(result == 0x448ebbc9e1a31220a2f3830c18eef61b9bd070e5084b7fa2a359fe729184c7);\n\n // to show correctness of the current ver (truncate one byte) vs old ver (mod full bytes):\n let result_bytes = std::hash::sha256(full_buffer);\n let truncated_field = crate::utils::field::field_from_bytes_32_trunc(result_bytes);\n assert(truncated_field == result);\n let mod_res = result + (result_bytes[31] as Field);\n assert(mod_res == 0x448ebbc9e1a31220a2f3830c18eef61b9bd070e5084b7fa2a359fe729184e0);\n}\n\n#[test]\nfn compute_l2_l1_hash() {\n // All zeroes\n let hash_result =\n compute_l2_to_l1_hash(AztecAddress::from_field(0), EthAddress::zero(), 0, 0, 0);\n assert(hash_result == 0xb393978842a0fa3d3e1470196f098f473f9678e72463cb65ec4ab5581856c2);\n\n // Non-zero case\n let hash_result = compute_l2_to_l1_hash(\n AztecAddress::from_field(1),\n EthAddress::from_field(3),\n 5,\n 2,\n 4,\n );\n assert(hash_result == 0x3f88c1044a05e5340ed20466276500f6d45ca5603913b9091e957161734e16);\n}\n\n#[test]\nfn silo_l2_to_l1_message_matches_typescript() {\n let version = 4;\n let chainId = 5;\n\n let hash = silo_l2_to_l1_message(\n ScopedL2ToL1Message {\n message: L2ToL1Message { recipient: EthAddress::from_field(1), content: 2, counter: 0 },\n contract_address: AztecAddress::from_field(3),\n },\n version,\n chainId,\n );\n\n // The following value was generated by `l2_to_l1_message.test.ts`\n let hash_from_typescript = 0x00c6155d69febb9d5039b374dd4f77bf57b7c881709aa524a18acaa0bd57476a;\n\n assert_eq(hash, hash_from_typescript);\n}\n" }, "26": { "path": "std/hash/poseidon2.nr", "source": "use crate::default::Default;\nuse crate::hash::Hasher;\n\ncomptime global RATE: u32 = 3;\n\npub struct Poseidon2 {\n cache: [Field; 3],\n state: [Field; 4],\n cache_size: u32,\n squeeze_mode: bool, // 0 => absorb, 1 => squeeze\n}\n\nimpl Poseidon2 {\n #[no_predicates]\n pub fn hash(input: [Field; N], message_size: u32) -> Field {\n Poseidon2::hash_internal(input, message_size, message_size != N)\n }\n\n pub fn new(iv: Field) -> Poseidon2 {\n let mut result =\n Poseidon2 { cache: [0; 3], state: [0; 4], cache_size: 0, squeeze_mode: false };\n result.state[RATE] = iv;\n result\n }\n\n fn perform_duplex(&mut self) {\n // add the cache into sponge state\n for i in 0..RATE {\n // We effectively zero-pad the cache by only adding to the state\n // cache that is less than the specified `cache_size`\n if i < self.cache_size {\n self.state[i] += self.cache[i];\n }\n }\n self.state = crate::hash::poseidon2_permutation(self.state, 4);\n }\n\n fn absorb(&mut self, input: Field) {\n assert(!self.squeeze_mode);\n if self.cache_size == RATE {\n // If we're absorbing, and the cache is full, apply the sponge permutation to compress the cache\n self.perform_duplex();\n self.cache[0] = input;\n self.cache_size = 1;\n } else {\n // If we're absorbing, and the cache is not full, add the input into the cache\n self.cache[self.cache_size] = input;\n self.cache_size += 1;\n }\n }\n\n fn squeeze(&mut self) -> Field {\n assert(!self.squeeze_mode);\n // If we're in absorb mode, apply sponge permutation to compress the cache.\n self.perform_duplex();\n self.squeeze_mode = true;\n\n // Pop one item off the top of the permutation and return it.\n self.state[0]\n }\n\n fn hash_internal(\n input: [Field; N],\n in_len: u32,\n is_variable_length: bool,\n ) -> Field {\n let two_pow_64 = 18446744073709551616;\n let iv: Field = (in_len as Field) * two_pow_64;\n let mut sponge = Poseidon2::new(iv);\n for i in 0..input.len() {\n if i < in_len {\n sponge.absorb(input[i]);\n }\n }\n\n // In the case where the hash preimage is variable-length, we append `1` to the end of the input, to distinguish\n // from fixed-length hashes. (the combination of this additional field element + the hash IV ensures\n // fixed-length and variable-length hashes do not collide)\n if is_variable_length {\n sponge.absorb(1);\n }\n sponge.squeeze()\n }\n}\n\npub struct Poseidon2Hasher {\n _state: [Field],\n}\n\nimpl Hasher for Poseidon2Hasher {\n fn finish(self) -> Field {\n let iv: Field = (self._state.len() as Field) * 18446744073709551616; // iv = (self._state.len() << 64)\n let mut sponge = Poseidon2::new(iv);\n for i in 0..self._state.len() {\n sponge.absorb(self._state[i]);\n }\n sponge.squeeze()\n }\n\n fn write(&mut self, input: Field) {\n self._state = self._state.push_back(input);\n }\n}\n\nimpl Default for Poseidon2Hasher {\n fn default() -> Self {\n Poseidon2Hasher { _state: &[] }\n }\n}\n" }, - "267": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/noir-protocol-circuits/crates/types/src/poseidon2.nr", - "source": "use crate::constants::TWO_POW_64;\n\n// NB: This is a clone of noir/noir-repo/noir_stdlib/src/hash/poseidon2.nr\n// It exists as we sometimes need to perform custom absorption, but the stdlib version\n// has a private absorb() method (it's also designed to just be a hasher)\n// Can be removed when standalone noir poseidon lib exists: See noir#6679\n\ncomptime global RATE: u32 = 3;\n\npub struct Poseidon2Sponge {\n pub cache: [Field; 3],\n pub state: [Field; 4],\n pub cache_size: u32,\n pub squeeze_mode: bool, // 0 => absorb, 1 => squeeze\n}\n\nimpl Poseidon2Sponge {\n #[no_predicates]\n pub fn hash(input: [Field; N], message_size: u32) -> Field {\n Poseidon2Sponge::hash_internal(input, message_size, message_size != N)\n }\n\n pub(crate) fn new(iv: Field) -> Poseidon2Sponge {\n let mut result =\n Poseidon2Sponge { cache: [0; 3], state: [0; 4], cache_size: 0, squeeze_mode: false };\n result.state[RATE] = iv;\n result\n }\n\n fn perform_duplex(&mut self) {\n // add the cache into sponge state\n for i in 0..RATE {\n // We effectively zero-pad the cache by only adding to the state\n // cache that is less than the specified `cache_size`\n if i < self.cache_size {\n self.state[i] += self.cache[i];\n }\n }\n self.state = std::hash::poseidon2_permutation(self.state, 4);\n }\n\n pub fn absorb(&mut self, input: Field) {\n assert(!self.squeeze_mode);\n if self.cache_size == RATE {\n // If we're absorbing, and the cache is full, apply the sponge permutation to compress the cache\n self.perform_duplex();\n self.cache[0] = input;\n self.cache_size = 1;\n } else {\n // If we're absorbing, and the cache is not full, add the input into the cache\n self.cache[self.cache_size] = input;\n self.cache_size += 1;\n }\n }\n\n pub fn squeeze(&mut self) -> Field {\n assert(!self.squeeze_mode);\n // If we're in absorb mode, apply sponge permutation to compress the cache.\n self.perform_duplex();\n self.squeeze_mode = true;\n\n // Pop one item off the top of the permutation and return it.\n self.state[0]\n }\n\n fn hash_internal(\n input: [Field; N],\n in_len: u32,\n is_variable_length: bool,\n ) -> Field {\n let iv: Field = (in_len as Field) * TWO_POW_64;\n let mut sponge = Poseidon2Sponge::new(iv);\n for i in 0..input.len() {\n if i < in_len {\n sponge.absorb(input[i]);\n }\n }\n\n // In the case where the hash preimage is variable-length, we append `1` to the end of the input, to distinguish\n // from fixed-length hashes. (the combination of this additional field element + the hash IV ensures\n // fixed-length and variable-length hashes do not collide)\n if is_variable_length {\n sponge.absorb(1);\n }\n sponge.squeeze()\n }\n}\n" - }, - "279": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/noir-protocol-circuits/crates/types/src/storage/map.nr", + "280": { + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/noir-protocol-circuits/crates/types/src/storage/map.nr", "source": "use crate::{hash::poseidon2_hash, traits::ToField};\n\npub fn derive_storage_slot_in_map(storage_slot: Field, key: K) -> Field\nwhere\n K: ToField,\n{\n poseidon2_hash([storage_slot, key.to_field()])\n}\n\nmod test {\n use crate::{address::AztecAddress, storage::map::derive_storage_slot_in_map, traits::FromField};\n\n #[test]\n fn test_derive_storage_slot_in_map_matches_typescript() {\n let map_slot = 0x132258fb6962c4387ba659d9556521102d227549a386d39f0b22d1890d59c2b5;\n let key = AztecAddress::from_field(\n 0x302dbc2f9b50a73283d5fb2f35bc01eae8935615817a0b4219a057b2ba8a5a3f,\n );\n\n let slot = derive_storage_slot_in_map(map_slot, key);\n\n // The following value was generated by `map_slot.test.ts`\n let slot_from_typescript =\n 0x15b9fe39449affd8b377461263e9d2b610b9ad40580553500b4e41d9cbd887ac;\n\n assert_eq(slot, slot_from_typescript);\n }\n}\n" }, - "292": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/noir-protocol-circuits/crates/types/src/traits.nr", - "source": "use crate::meta::{derive_deserialize, derive_serialize};\nuse crate::utils::field::field_from_bytes;\n\n// Trait: is_empty\n//\n// The general is_empty trait checks if a data type is is empty,\n// and it defines empty for the basic data types as 0.\n//\n// If a Field is equal to zero, then it is regarded as zero.\n// We will go with this definition for now, however it can be problematic\n// if a value can actually be zero. In a future refactor, we can\n// use the optional type for safety. Doing it now would lead to a worse devex\n// and would make it harder to sync up with the cpp code.\n// Preferred over Default trait to convey intent, as default doesn't necessarily mean empty.\npub trait Empty {\n fn empty() -> Self;\n}\n\nimpl Empty for Field {\n fn empty() -> Self {\n 0\n }\n}\n\nimpl Empty for u1 {\n fn empty() -> Self {\n 0\n }\n}\nimpl Empty for u8 {\n fn empty() -> Self {\n 0\n }\n}\nimpl Empty for u32 {\n fn empty() -> Self {\n 0\n }\n}\nimpl Empty for u64 {\n fn empty() -> Self {\n 0\n }\n}\nimpl Empty for U128 {\n fn empty() -> Self {\n U128::from_integer(0)\n }\n}\n\npub fn is_empty(item: T) -> bool\nwhere\n T: Empty + Eq,\n{\n item.eq(T::empty())\n}\n\npub fn is_empty_array(array: [T; N]) -> bool\nwhere\n T: Empty + Eq,\n{\n array.all(|elem| is_empty(elem))\n}\n\npub trait Hash {\n fn hash(self) -> Field;\n}\n\npub trait ToField {\n fn to_field(self) -> Field;\n}\n\nimpl ToField for Field {\n fn to_field(self) -> Field {\n self\n }\n}\n\nimpl ToField for bool {\n fn to_field(self) -> Field {\n self as Field\n }\n}\nimpl ToField for u1 {\n fn to_field(self) -> Field {\n self as Field\n }\n}\nimpl ToField for u8 {\n fn to_field(self) -> Field {\n self as Field\n }\n}\nimpl ToField for u32 {\n fn to_field(self) -> Field {\n self as Field\n }\n}\nimpl ToField for u64 {\n fn to_field(self) -> Field {\n self as Field\n }\n}\nimpl ToField for U128 {\n fn to_field(self) -> Field {\n self.to_integer()\n }\n}\nimpl ToField for str {\n fn to_field(self) -> Field {\n assert(N < 32, \"String doesn't fit in a field, consider using Serialize instead\");\n field_from_bytes(self.as_bytes(), true)\n }\n}\n\npub trait FromField {\n fn from_field(value: Field) -> Self;\n}\n\nimpl FromField for Field {\n fn from_field(value: Field) -> Self {\n value\n }\n}\n\nimpl FromField for bool {\n fn from_field(value: Field) -> Self {\n value as bool\n }\n}\nimpl FromField for u1 {\n fn from_field(value: Field) -> Self {\n value as u1\n }\n}\nimpl FromField for u8 {\n fn from_field(value: Field) -> Self {\n value as u8\n }\n}\nimpl FromField for u32 {\n fn from_field(value: Field) -> Self {\n value as u32\n }\n}\nimpl FromField for u64 {\n fn from_field(value: Field) -> Self {\n value as u64\n }\n}\nimpl FromField for U128 {\n fn from_field(value: Field) -> Self {\n U128::from_integer(value)\n }\n}\n\n// docs:start:serialize\n#[derive_via(derive_serialize)]\npub trait Serialize {\n fn serialize(self) -> [Field; N];\n}\n// docs:end:serialize\n\nimpl Serialize for str {\n fn serialize(self) -> [Field; N] {\n let bytes = self.as_bytes();\n let mut fields = [0; N];\n for i in 0..bytes.len() {\n fields[i] = bytes[i] as Field;\n }\n fields\n }\n}\n\n// docs:start:deserialize\n#[derive_via(derive_deserialize)]\npub trait Deserialize {\n fn deserialize(fields: [Field; N]) -> Self;\n}\n// docs:end:deserialize\n\nimpl Deserialize for str {\n fn deserialize(fields: [Field; N]) -> Self {\n str::from(fields.map(|value| value as u8))\n }\n}\n" + "293": { + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/noir-protocol-circuits/crates/types/src/traits.nr", + "source": "use crate::meta::{derive_deserialize, derive_serialize};\nuse crate::utils::field::field_from_bytes;\n\n// Trait: is_empty\n//\n// The general is_empty trait checks if a data type is is empty,\n// and it defines empty for the basic data types as 0.\n//\n// If a Field is equal to zero, then it is regarded as zero.\n// We will go with this definition for now, however it can be problematic\n// if a value can actually be zero. In a future refactor, we can\n// use the optional type for safety. Doing it now would lead to a worse devex\n// and would make it harder to sync up with the cpp code.\n// Preferred over Default trait to convey intent, as default doesn't necessarily mean empty.\npub trait Empty {\n fn empty() -> Self;\n}\n\nimpl Empty for Field {\n fn empty() -> Self {\n 0\n }\n}\n\nimpl Empty for u1 {\n fn empty() -> Self {\n 0\n }\n}\nimpl Empty for u8 {\n fn empty() -> Self {\n 0\n }\n}\nimpl Empty for u32 {\n fn empty() -> Self {\n 0\n }\n}\nimpl Empty for u64 {\n fn empty() -> Self {\n 0\n }\n}\nimpl Empty for U128 {\n fn empty() -> Self {\n U128::from_integer(0)\n }\n}\n\npub fn is_empty(item: T) -> bool\nwhere\n T: Empty + Eq,\n{\n item.eq(T::empty())\n}\n\npub fn is_empty_array(array: [T; N]) -> bool\nwhere\n T: Empty + Eq,\n{\n array.all(|elem| is_empty(elem))\n}\n\npub trait Hash {\n fn hash(self) -> Field;\n}\n\npub trait ToField {\n fn to_field(self) -> Field;\n}\n\nimpl ToField for Field {\n fn to_field(self) -> Field {\n self\n }\n}\n\nimpl ToField for bool {\n fn to_field(self) -> Field {\n self as Field\n }\n}\nimpl ToField for u1 {\n fn to_field(self) -> Field {\n self as Field\n }\n}\nimpl ToField for u8 {\n fn to_field(self) -> Field {\n self as Field\n }\n}\nimpl ToField for u32 {\n fn to_field(self) -> Field {\n self as Field\n }\n}\nimpl ToField for u64 {\n fn to_field(self) -> Field {\n self as Field\n }\n}\nimpl ToField for U128 {\n fn to_field(self) -> Field {\n self.to_integer()\n }\n}\nimpl ToField for str {\n fn to_field(self) -> Field {\n assert(N < 32, \"String doesn't fit in a field, consider using Serialize instead\");\n field_from_bytes(self.as_bytes(), true)\n }\n}\n\npub trait FromField {\n fn from_field(value: Field) -> Self;\n}\n\nimpl FromField for Field {\n fn from_field(value: Field) -> Self {\n value\n }\n}\n\nimpl FromField for bool {\n fn from_field(value: Field) -> Self {\n value as bool\n }\n}\nimpl FromField for u1 {\n fn from_field(value: Field) -> Self {\n value as u1\n }\n}\nimpl FromField for u8 {\n fn from_field(value: Field) -> Self {\n value as u8\n }\n}\nimpl FromField for u32 {\n fn from_field(value: Field) -> Self {\n value as u32\n }\n}\nimpl FromField for u64 {\n fn from_field(value: Field) -> Self {\n value as u64\n }\n}\nimpl FromField for U128 {\n fn from_field(value: Field) -> Self {\n U128::from_integer(value)\n }\n}\n\n// docs:start:serialize\n/// Trait for serializing Noir types into arrays of Fields.\n///\n/// An implementation of the Serialize trait has to follow Noir's intrinsic serialization (each member of a struct\n/// converted directly into one or more Fields without any packing or compression). This trait (and Deserialize) are\n/// typically used to communicate between Noir and TypeScript (via oracles and function arguments).\n///\n/// # On Following Noir's Intrinsic Serialization\n/// When calling a Noir function from TypeScript (TS), first the function arguments are serialized into an array\n/// of fields. This array is then included in the initial witness. Noir's intrinsic serialization is then used\n/// to deserialize the arguments from the witness. When the same Noir function is called from Noir this Serialize trait\n/// is used instead of the serialization in TS. For this reason we need to have a match between TS serialization,\n/// Noir's intrinsic serialization and the implementation of this trait. If there is a mismatch, the function calls\n/// fail with an arguments hash mismatch error message.\n///\n/// # Type Parameters\n/// * `N` - The length of the output Field array, known at compile time\n///\n/// # Example\n/// ```\n/// impl Serialize for str {\n/// fn serialize(self) -> [Field; N] {\n/// let bytes = self.as_bytes();\n/// let mut fields = [0; N];\n/// for i in 0..bytes.len() {\n/// fields[i] = bytes[i] as Field; // Each byte gets its own Field\n/// }\n/// fields\n/// }\n/// }\n/// ```\n#[derive_via(derive_serialize)]\npub trait Serialize {\n fn serialize(self) -> [Field; N];\n}\n// docs:end:serialize\n\nimpl Serialize for str {\n fn serialize(self) -> [Field; N] {\n let bytes = self.as_bytes();\n let mut fields = [0; N];\n for i in 0..bytes.len() {\n fields[i] = bytes[i] as Field;\n }\n fields\n }\n}\n\n// docs:start:deserialize\n/// Trait for deserializing Noir types from arrays of Fields.\n///\n/// An implementation of the Deserialize trait has to follow Noir's intrinsic serialization (each member of a struct\n/// converted directly into one or more Fields without any packing or compression). This trait is typically used when\n/// deserializing return values from function calls in Noir. Since the same function could be called from TypeScript\n/// (TS), in which case the TS deserialization would get used, we need to have a match between the 2.\n///\n/// # Type Parameters\n/// * `N` - The length of the input Field array, known at compile time\n///\n/// # Example\n/// ```\n/// impl Deserialize for str {\n/// fn deserialize(fields: [Field; N]) -> Self {\n/// str::from(fields.map(|value| value as u8))\n/// }\n/// }\n/// ```\n#[derive_via(derive_deserialize)]\npub trait Deserialize {\n fn deserialize(fields: [Field; N]) -> Self;\n}\n// docs:end:deserialize\n\nimpl Deserialize for str {\n fn deserialize(fields: [Field; N]) -> Self {\n str::from(fields.map(|value| value as u8))\n }\n}\n\n/// Trait for efficiently packing and unpacking Noir types into and from arrays of Fields.\n///\n/// The `Packable` trait allows types to be serialized and deserialized with a focus on minimizing the size of\n/// the resulting Field array. This trait is used when storage efficiency is critical (e.g. when storing data\n/// in the contract's public storage).\n///\n/// # Type Parameters\n/// * `N` - The length of the Field array, known at compile time.\npub trait Packable {\n /// Packs the current value into a compact array of `Field` elements.\n fn pack(self) -> [Field; N];\n\n /// Unpacks a compact array of `Field` elements into the original value.\n fn unpack(fields: [Field; N]) -> Self;\n}\n" }, - "296": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/noir-protocol-circuits/crates/types/src/type_serialization.nr", - "source": "use crate::traits::{Deserialize, Serialize};\n\nglobal BOOL_SERIALIZED_LEN: u32 = 1;\nglobal U8_SERIALIZED_LEN: u32 = 1;\nglobal U16_SERIALIZED_LEN: u32 = 1;\nglobal U32_SERIALIZED_LEN: u32 = 1;\nglobal U64_SERIALIZED_LEN: u32 = 1;\nglobal U128_SERIALIZED_LEN: u32 = 1;\nglobal FIELD_SERIALIZED_LEN: u32 = 1;\nglobal I8_SERIALIZED_LEN: u32 = 1;\nglobal I16_SERIALIZED_LEN: u32 = 1;\nglobal I32_SERIALIZED_LEN: u32 = 1;\nglobal I64_SERIALIZED_LEN: u32 = 1;\n\nimpl Serialize for bool {\n fn serialize(self) -> [Field; BOOL_SERIALIZED_LEN] {\n [self as Field]\n }\n}\n\nimpl Deserialize for bool {\n fn deserialize(fields: [Field; BOOL_SERIALIZED_LEN]) -> bool {\n fields[0] as bool\n }\n}\n\nimpl Serialize for u8 {\n fn serialize(self) -> [Field; U8_SERIALIZED_LEN] {\n [self as Field]\n }\n}\n\nimpl Deserialize for u8 {\n fn deserialize(fields: [Field; U8_SERIALIZED_LEN]) -> Self {\n fields[0] as u8\n }\n}\n\nimpl Serialize for u16 {\n fn serialize(self) -> [Field; U16_SERIALIZED_LEN] {\n [self as Field]\n }\n}\n\nimpl Deserialize for u16 {\n fn deserialize(fields: [Field; U16_SERIALIZED_LEN]) -> Self {\n fields[0] as u16\n }\n}\n\nimpl Serialize for u32 {\n fn serialize(self) -> [Field; U32_SERIALIZED_LEN] {\n [self as Field]\n }\n}\n\nimpl Deserialize for u32 {\n fn deserialize(fields: [Field; U32_SERIALIZED_LEN]) -> Self {\n fields[0] as u32\n }\n}\n\nimpl Serialize for u64 {\n fn serialize(self) -> [Field; U64_SERIALIZED_LEN] {\n [self as Field]\n }\n}\n\nimpl Deserialize for u64 {\n fn deserialize(fields: [Field; U64_SERIALIZED_LEN]) -> Self {\n fields[0] as u64\n }\n}\n\nimpl Serialize for U128 {\n fn serialize(self) -> [Field; U128_SERIALIZED_LEN] {\n [self.to_integer()]\n }\n}\n\nimpl Deserialize for U128 {\n fn deserialize(fields: [Field; U128_SERIALIZED_LEN]) -> Self {\n U128::from_integer(fields[0])\n }\n}\n\nimpl Serialize for Field {\n fn serialize(self) -> [Field; FIELD_SERIALIZED_LEN] {\n [self]\n }\n}\n\nimpl Deserialize for Field {\n fn deserialize(fields: [Field; FIELD_SERIALIZED_LEN]) -> Self {\n fields[0]\n }\n}\n\nimpl Serialize for i8 {\n fn serialize(self) -> [Field; I8_SERIALIZED_LEN] {\n [self as Field]\n }\n}\n\nimpl Deserialize for i8 {\n fn deserialize(fields: [Field; I8_SERIALIZED_LEN]) -> Self {\n fields[0] as i8\n }\n}\n\nimpl Serialize for i16 {\n fn serialize(self) -> [Field; I16_SERIALIZED_LEN] {\n [self as Field]\n }\n}\n\nimpl Deserialize for i16 {\n fn deserialize(fields: [Field; I16_SERIALIZED_LEN]) -> Self {\n fields[0] as i16\n }\n}\n\nimpl Serialize for i32 {\n fn serialize(self) -> [Field; I32_SERIALIZED_LEN] {\n [self as Field]\n }\n}\n\nimpl Deserialize for i32 {\n fn deserialize(fields: [Field; I32_SERIALIZED_LEN]) -> Self {\n fields[0] as i32\n }\n}\n\nimpl Serialize for i64 {\n fn serialize(self) -> [Field; I64_SERIALIZED_LEN] {\n [self as Field]\n }\n}\n\nimpl Deserialize for i64 {\n fn deserialize(fields: [Field; I64_SERIALIZED_LEN]) -> Self {\n fields[0] as i64\n }\n}\n\nimpl Serialize for [T; N]\nwhere\n T: Serialize,\n{\n fn serialize(self) -> [Field; N * M] {\n let mut result: [Field; N * M] = std::mem::zeroed();\n let mut serialized: [Field; M] = std::mem::zeroed();\n for i in 0..N {\n serialized = self[i].serialize();\n for j in 0..M {\n result[i * M + j] = serialized[j];\n }\n }\n result\n }\n}\n\nimpl Deserialize for [T; N]\nwhere\n T: Deserialize,\n{\n fn deserialize(fields: [Field; N * M]) -> Self {\n let mut reader = crate::utils::reader::Reader::new(fields);\n let mut result: [T; N] = std::mem::zeroed();\n reader.read_struct_array::(Deserialize::deserialize, result)\n }\n}\n\n#[test]\nfn test_u16_serialization() {\n let a: u16 = 10;\n assert_eq(a, u16::deserialize(a.serialize()));\n}\n\n#[test]\nfn test_i8_serialization() {\n let a: i8 = -10;\n assert_eq(a, i8::deserialize(a.serialize()));\n}\n\n#[test]\nfn test_i16_serialization() {\n let a: i16 = -10;\n assert_eq(a, i16::deserialize(a.serialize()));\n}\n\n#[test]\nfn test_i32_serialization() {\n let a: i32 = -10;\n assert_eq(a, i32::deserialize(a.serialize()));\n}\n\n#[test]\nfn test_i64_serialization() {\n let a: i64 = -10;\n assert_eq(a, i64::deserialize(a.serialize()));\n}\n" + "297": { + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/noir-protocol-circuits/crates/types/src/type_packing.nr", + "source": "use crate::traits::{Packable, ToField};\n\nglobal BOOL_PACKED_LEN: u32 = 1;\nglobal U8_PACKED_LEN: u32 = 1;\nglobal U16_PACKED_LEN: u32 = 1;\nglobal U32_PACKED_LEN: u32 = 1;\nglobal U64_PACKED_LEN: u32 = 1;\nglobal U128_PACKED_LEN: u32 = 1;\nglobal FIELD_PACKED_LEN: u32 = 1;\nglobal I8_PACKED_LEN: u32 = 1;\nglobal I16_PACKED_LEN: u32 = 1;\nglobal I32_PACKED_LEN: u32 = 1;\nglobal I64_PACKED_LEN: u32 = 1;\n\nimpl Packable for bool {\n fn pack(self) -> [Field; BOOL_PACKED_LEN] {\n [self as Field]\n }\n\n fn unpack(fields: [Field; BOOL_PACKED_LEN]) -> bool {\n fields[0] as bool\n }\n}\n\nimpl Packable for u8 {\n fn pack(self) -> [Field; U8_PACKED_LEN] {\n [self as Field]\n }\n\n fn unpack(fields: [Field; U8_PACKED_LEN]) -> Self {\n fields[0] as u8\n }\n}\n\nimpl Packable for u16 {\n fn pack(self) -> [Field; U16_PACKED_LEN] {\n [self as Field]\n }\n\n fn unpack(fields: [Field; U16_PACKED_LEN]) -> Self {\n fields[0] as u16\n }\n}\n\nimpl Packable for u32 {\n fn pack(self) -> [Field; U32_PACKED_LEN] {\n [self as Field]\n }\n\n fn unpack(fields: [Field; U32_PACKED_LEN]) -> Self {\n fields[0] as u32\n }\n}\n\nimpl Packable for u64 {\n fn pack(self) -> [Field; U64_PACKED_LEN] {\n [self as Field]\n }\n\n fn unpack(fields: [Field; U64_PACKED_LEN]) -> Self {\n fields[0] as u64\n }\n}\n\nimpl Packable for U128 {\n fn pack(self) -> [Field; U128_PACKED_LEN] {\n [self.to_field()]\n }\n\n fn unpack(fields: [Field; U128_PACKED_LEN]) -> Self {\n U128::from_integer(fields[0])\n }\n}\n\nimpl Packable for Field {\n fn pack(self) -> [Field; FIELD_PACKED_LEN] {\n [self]\n }\n\n fn unpack(fields: [Field; FIELD_PACKED_LEN]) -> Self {\n fields[0]\n }\n}\n\nimpl Packable for i8 {\n fn pack(self) -> [Field; I8_PACKED_LEN] {\n [self as Field]\n }\n\n fn unpack(fields: [Field; I8_PACKED_LEN]) -> Self {\n fields[0] as i8\n }\n}\n\nimpl Packable for i16 {\n fn pack(self) -> [Field; I16_PACKED_LEN] {\n [self as Field]\n }\n\n fn unpack(fields: [Field; I16_PACKED_LEN]) -> Self {\n fields[0] as i16\n }\n}\n\nimpl Packable for i32 {\n fn pack(self) -> [Field; I32_PACKED_LEN] {\n [self as Field]\n }\n\n fn unpack(fields: [Field; I32_PACKED_LEN]) -> Self {\n fields[0] as i32\n }\n}\n\nimpl Packable for i64 {\n fn pack(self) -> [Field; I64_PACKED_LEN] {\n [self as Field]\n }\n\n fn unpack(fields: [Field; I64_PACKED_LEN]) -> Self {\n fields[0] as i64\n }\n}\n\nimpl Packable for [T; N]\nwhere\n T: Packable,\n{\n fn pack(self) -> [Field; N * M] {\n let mut result: [Field; N * M] = std::mem::zeroed();\n let mut serialized: [Field; M] = std::mem::zeroed();\n for i in 0..N {\n serialized = self[i].pack();\n for j in 0..M {\n result[i * M + j] = serialized[j];\n }\n }\n result\n }\n\n fn unpack(fields: [Field; N * M]) -> Self {\n let mut reader = crate::utils::reader::Reader::new(fields);\n let mut result: [T; N] = std::mem::zeroed();\n reader.read_struct_array::(Packable::unpack, result)\n }\n}\n\n#[test]\nfn test_u16_packing() {\n let a: u16 = 10;\n assert_eq(a, u16::unpack(a.pack()));\n}\n\n#[test]\nfn test_i8_packing() {\n let a: i8 = -10;\n assert_eq(a, i8::unpack(a.pack()));\n}\n\n#[test]\nfn test_i16_packing() {\n let a: i16 = -10;\n assert_eq(a, i16::unpack(a.pack()));\n}\n\n#[test]\nfn test_i32_packing() {\n let a: i32 = -10;\n assert_eq(a, i32::unpack(a.pack()));\n}\n\n#[test]\nfn test_i64_packing() {\n let a: i64 = -10;\n assert_eq(a, i64::unpack(a.pack()));\n}\n" }, - "312": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr", + "314": { + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr", "source": "pub mod assert_array_appended;\npub mod assert_array_prepended;\npub mod assert_combined_array;\npub mod assert_combined_transformed_array;\npub mod assert_exposed_sorted_transformed_value_array;\npub mod assert_sorted_array;\npub mod assert_sorted_transformed_value_array;\npub mod assert_split_sorted_transformed_value_arrays;\npub mod assert_split_transformed_value_arrays;\npub mod get_sorted_result;\npub mod get_sorted_tuple;\npub mod sort_by;\npub mod sort_by_counter;\n\n// Re-exports.\npub use assert_array_appended::{\n assert_array_appended, assert_array_appended_and_scoped, assert_array_appended_reversed,\n assert_array_appended_scoped,\n};\npub use assert_array_prepended::assert_array_prepended;\npub use assert_combined_array::{assert_combined_array, combine_arrays};\npub use assert_combined_transformed_array::{\n assert_combined_transformed_array, combine_and_transform_arrays,\n};\npub use assert_exposed_sorted_transformed_value_array::{\n assert_exposed_sorted_transformed_value_array,\n get_order_hints::{get_order_hints_asc, get_order_hints_desc, OrderHint},\n};\npub use assert_sorted_array::assert_sorted_array;\npub use assert_sorted_transformed_value_array::{\n assert_sorted_transformed_value_array, assert_sorted_transformed_value_array_capped_size,\n};\npub use assert_split_sorted_transformed_value_arrays::{\n assert_split_sorted_transformed_value_arrays_asc,\n assert_split_sorted_transformed_value_arrays_desc,\n get_split_order_hints::{get_split_order_hints_asc, get_split_order_hints_desc, SplitOrderHints},\n};\npub use assert_split_transformed_value_arrays::assert_split_transformed_value_arrays;\npub use get_sorted_result::{get_sorted_result, SortedResult};\npub use sort_by_counter::{sort_by_counter_asc, sort_by_counter_desc};\n\nuse crate::traits::{Empty, is_empty};\n\npub fn subarray(\n src: [Field; SRC_LEN],\n offset: u32,\n) -> [Field; DST_LEN] {\n assert(offset + DST_LEN <= SRC_LEN, \"offset too large\");\n\n let mut dst: [Field; DST_LEN] = std::mem::zeroed();\n for i in 0..DST_LEN {\n dst[i] = src[i + offset];\n }\n\n dst\n}\n\n// Helper function to convert a validated array to BoundedVec.\n// Important: Only use it for validated arrays: validate_array(array) should be true.\npub unconstrained fn array_to_bounded_vec(array: [T; N]) -> BoundedVec\nwhere\n T: Empty + Eq,\n{\n let len = array_length(array);\n BoundedVec::from_parts_unchecked(array, len)\n}\n\n// Helper function to find the index of the first element in an array that satisfies a given predicate. If the element\n// is not found, the function returns N as the index.\npub unconstrained fn find_index_hint(\n array: [T; N],\n find: fn[Env](T) -> bool,\n) -> u32 {\n let mut index = N;\n for i in 0..N {\n // We check `index == N` to ensure that we only update the index if we haven't found a match yet.\n if (index == N) & find(array[i]) {\n index = i;\n }\n }\n index\n}\n\n// Routine which validates that all zero values of an array form a contiguous region at the end, i.e.,\n// of the form: [*,*,*...,0,0,0,0] where any * is non-zero. Note that a full array of non-zero values is\n// valid.\npub fn validate_array(array: [T; N]) -> u32\nwhere\n T: Empty + Eq,\n{\n let mut seen_empty = false;\n let mut length = 0;\n for i in 0..N {\n if is_empty(array[i]) {\n seen_empty = true;\n } else {\n assert(seen_empty == false, \"invalid array\");\n length += 1;\n }\n }\n length\n}\n\n// Helper function to count the number of non-empty elements in a validated array.\n// Important: Only use it for validated arrays where validate_array(array) returns true,\n// which ensures that:\n// 1. All elements before the first empty element are non-empty\n// 2. All elements after and including the first empty element are empty\n// 3. The array forms a contiguous sequence of non-empty elements followed by empty elements\npub fn array_length(array: [T; N]) -> u32\nwhere\n T: Empty + Eq,\n{\n // We get the length by checking the index of the first empty element.\n\n /// Safety: This is safe because we have validated the array (see function doc above) and the emptiness\n /// of the element and non-emptiness of the previous element is checked below.\n let length = unsafe { find_index_hint(array, |elem: T| is_empty(elem)) };\n if length != 0 {\n assert(!is_empty(array[length - 1]));\n }\n if length != N {\n assert(is_empty(array[length]));\n }\n length\n}\n\npub fn array_concat(array1: [T; N], array2: [T; M]) -> [T; N + M] {\n let mut result = [array1[0]; N + M];\n for i in 1..N {\n result[i] = array1[i];\n }\n for i in 0..M {\n result[i + N] = array2[i];\n }\n result\n}\n\npub fn array_merge(array1: [T; N], array2: [T; N]) -> [T; N]\nwhere\n T: Empty + Eq,\n{\n let mut result: [T; N] = [T::empty(); N];\n let mut i = 0;\n for elem in array1 {\n if !is_empty(elem) {\n result[i] = elem;\n i += 1;\n }\n }\n for elem in array2 {\n if !is_empty(elem) {\n result[i] = elem;\n i += 1;\n }\n }\n result\n}\n\n// Helper fn to create a subarray from a given array\npub fn array_splice(array: [T; N], offset: u32) -> [T; M]\nwhere\n T: Empty,\n{\n assert(M + offset <= N, \"Subarray length larger than array length\");\n let mut result: [T; M] = [T::empty(); M];\n for i in 0..M {\n result[i] = array[offset + i];\n }\n result\n}\n\npub fn check_permutation(\n original_array: [T; N],\n permuted_array: [T; N],\n original_indexes: [u32; N],\n)\nwhere\n T: Eq + Empty,\n{\n let mut seen_value = [false; N];\n for i in 0..N {\n let index = original_indexes[i];\n let original_value = original_array[index];\n assert(permuted_array[i].eq(original_value), \"Invalid index\");\n assert(!seen_value[index], \"Duplicated index\");\n seen_value[index] = true;\n }\n}\n\n#[test]\nfn smoke_validate_array() {\n let valid_array: [Field; 0] = [];\n assert(validate_array(valid_array) == 0);\n\n let valid_array = [0];\n assert(validate_array(valid_array) == 0);\n\n let valid_array = [3];\n assert(validate_array(valid_array) == 1);\n\n let valid_array = [1, 2, 3];\n assert(validate_array(valid_array) == 3);\n\n let valid_array = [1, 2, 3, 0];\n assert(validate_array(valid_array) == 3);\n\n let valid_array = [1, 2, 3, 0, 0];\n assert(validate_array(valid_array) == 3);\n}\n\n#[test(should_fail_with = \"invalid array\")]\nfn smoke_validate_array_invalid_case0() {\n let invalid_array = [0, 1];\n let _ = validate_array(invalid_array);\n}\n\n#[test(should_fail_with = \"invalid array\")]\nfn smoke_validate_array_invalid_case1() {\n let invalid_array = [1, 0, 0, 1, 0];\n let _ = validate_array(invalid_array);\n}\n\n#[test(should_fail_with = \"invalid array\")]\nfn smoke_validate_array_invalid_case2() {\n let invalid_array = [0, 0, 0, 0, 1];\n let _ = validate_array(invalid_array);\n}\n\n#[test]\nfn test_empty_array_length() {\n assert_eq(array_length([0]), 0);\n assert_eq(array_length([0, 0, 0]), 0);\n}\n\n#[test]\nfn test_array_length() {\n assert_eq(array_length([123]), 1);\n assert_eq(array_length([123, 0, 0]), 1);\n assert_eq(array_length([123, 456]), 2);\n assert_eq(array_length([123, 456, 0]), 2);\n}\n\n#[test]\nfn test_array_length_invalid_arrays() {\n // Result can be misleading (but correct) for invalid arrays.\n assert_eq(array_length([0, 0, 123]), 0);\n assert_eq(array_length([0, 123, 0]), 0);\n assert_eq(array_length([0, 123, 456]), 0);\n assert_eq(array_length([123, 0, 456]), 1);\n}\n\n#[test]\nunconstrained fn find_index_greater_than_min() {\n let values = [10, 20, 30, 40];\n let min = 22;\n let index = find_index_hint(values, |v: Field| min.lt(v));\n assert_eq(index, 2);\n}\n\n#[test]\nunconstrained fn find_index_not_found() {\n let values = [10, 20, 30, 40];\n let min = 100;\n let index = find_index_hint(values, |v: Field| min.lt(v));\n assert_eq(index, 4);\n}\n\n#[test]\nfn test_array_concat() {\n let array0 = [1, 2, 3];\n let array1 = [4, 5];\n let concatenated = array_concat(array0, array1);\n assert_eq(concatenated, [1, 2, 3, 4, 5]);\n}\n\n#[test]\nfn check_permutation_basic_test() {\n let original_array = [1, 2, 3];\n let permuted_array = [3, 1, 2];\n let indexes = [2, 0, 1];\n check_permutation(original_array, permuted_array, indexes);\n}\n\n#[test(should_fail_with = \"Duplicated index\")]\nfn check_permutation_duplicated_index() {\n let original_array = [0, 1, 0];\n let permuted_array = [1, 0, 0];\n let indexes = [1, 0, 0];\n check_permutation(original_array, permuted_array, indexes);\n}\n\n#[test(should_fail_with = \"Invalid index\")]\nfn check_permutation_invalid_index() {\n let original_array = [0, 1, 2];\n let permuted_array = [1, 0, 0];\n let indexes = [1, 0, 2];\n check_permutation(original_array, permuted_array, indexes);\n}\n" }, - "315": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/noir-protocol-circuits/crates/types/src/utils/reader.nr", + "317": { + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/noir-protocol-circuits/crates/types/src/utils/reader.nr", "source": "pub struct Reader {\n data: [Field; N],\n offset: u32,\n}\n\nimpl Reader {\n pub fn new(data: [Field; N]) -> Self {\n Self { data, offset: 0 }\n }\n\n pub fn read(&mut self) -> Field {\n let result = self.data[self.offset];\n self.offset += 1;\n result\n }\n\n pub fn read_u32(&mut self) -> u32 {\n self.read() as u32\n }\n\n pub fn read_bool(&mut self) -> bool {\n self.read() as bool\n }\n\n pub fn read_array(&mut self) -> [Field; K] {\n let mut result = [0; K];\n for i in 0..K {\n result[i] = self.data[self.offset + i];\n }\n self.offset += K;\n result\n }\n\n pub fn read_struct(&mut self, deserialise: fn([Field; K]) -> T) -> T {\n let result = deserialise(self.read_array());\n result\n }\n\n pub fn read_struct_array(\n &mut self,\n deserialise: fn([Field; K]) -> T,\n mut result: [T; C],\n ) -> [T; C] {\n for i in 0..C {\n result[i] = self.read_struct(deserialise);\n }\n result\n }\n\n pub fn finish(self) {\n assert(self.offset == self.data.len(), \"Reader did not read all data\");\n }\n}\n" }, "51": { @@ -2260,31 +544,19 @@ }, "62": { "path": "/home/filip/c/chicmoz/services/event-cannon/src/contract-projects/SimpleLogging/src/main.nr", - "source": "use dep::aztec::macros::aztec;\n\n#[aztec]\ncontract SimpleLogging {\n use dep::aztec::prelude::{Map, PublicMutable};\n use dep::aztec::{\n //keys::getters::get_public_keys,\n macros::{storage::storage, functions::{public, initializer, private, internal}},\n };\n #[storage]\n struct Storage {\n counters: Map, Context>,\n }\n\n #[public]\n #[initializer]\n fn constructor() {\n }\n\n #[private]\n fn increase_counter_private(counter_id: Field) {\n //let msg_sender_npk_m_hash = get_public_keys(context.msg_sender()).npk_m.hash();\n //let secret = context.request_nsk_app(msg_sender_npk_m_hash); // get secret key of caller of function\n //let nullifier = std::hash::pedersen_hash([context.msg_sender().to_field(), secret]); // derive nullifier from sender and secret\n //context.push_nullifier(nullifier);\n SimpleLogging::at(context.this_address()).add_to_counter_public(counter_id).enqueue(\n &mut context,\n );\n }\n\n #[public]\n #[internal]\n fn add_to_counter_public(counter_id: Field) {\n let new_counter_value = storage.counters.at(counter_id).read() + 1;\n storage.counters.at(counter_id).write(new_counter_value);\n }\n\n #[public]\n fn increase_counter_public(counter_id: Field) {\n context.emit_unencrypted_log(/*message=*/\"Counter increased public\");\n SimpleLogging::at(context.this_address()).add_to_counter_public(counter_id);\n }\n unconstrained fn get_counter_value(counter_id: Field) -> pub Field {\n storage.counters.at(counter_id).read()\n }\n}\n" - }, - "63": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/context/call_interfaces.nr", - "source": "use dep::protocol_types::{\n abis::function_selector::FunctionSelector, address::AztecAddress, traits::Deserialize,\n};\n\nuse crate::context::{gas::GasOpts, private_context::PrivateContext, public_context::PublicContext};\n\nuse crate::hash::hash_args;\nuse crate::oracle::execution_cache;\n\npub trait CallInterface {\n fn get_args(self) -> [Field];\n fn get_selector(self) -> FunctionSelector;\n fn get_name(self) -> str;\n fn get_contract_address(self) -> AztecAddress;\n fn get_is_static(self) -> bool;\n}\n\npub struct PrivateCallInterface {\n pub target_contract: AztecAddress,\n pub selector: FunctionSelector,\n pub name: str,\n pub args_hash: Field,\n pub args: [Field],\n pub return_type: T,\n pub is_static: bool,\n}\n\nimpl PrivateCallInterface {\n pub fn call(self, context: &mut PrivateContext) -> T\n where\n T: Deserialize,\n {\n execution_cache::store(self.args);\n let returns_hash = context.call_private_function_with_args_hash(\n self.target_contract,\n self.selector,\n self.args_hash,\n false,\n );\n let returns: T = returns_hash.get_preimage();\n returns\n }\n\n pub fn view(self, context: &mut PrivateContext) -> T\n where\n T: Deserialize,\n {\n execution_cache::store(self.args);\n let returns_hash = context.call_private_function_with_args_hash(\n self.target_contract,\n self.selector,\n self.args_hash,\n true,\n );\n returns_hash.get_preimage()\n }\n}\n\nimpl CallInterface for PrivateVoidCallInterface {\n fn get_args(self) -> [Field] {\n self.args\n }\n\n fn get_selector(self) -> FunctionSelector {\n self.selector\n }\n\n fn get_name(self) -> str {\n self.name\n }\n\n fn get_contract_address(self) -> AztecAddress {\n self.target_contract\n }\n\n fn get_is_static(self) -> bool {\n self.is_static\n }\n}\n\npub struct PrivateVoidCallInterface {\n pub target_contract: AztecAddress,\n pub selector: FunctionSelector,\n pub name: str,\n pub args_hash: Field,\n pub args: [Field],\n pub return_type: (),\n pub is_static: bool,\n}\n\nimpl PrivateVoidCallInterface {\n pub fn call(self, context: &mut PrivateContext) {\n execution_cache::store(self.args);\n context\n .call_private_function_with_args_hash(\n self.target_contract,\n self.selector,\n self.args_hash,\n false,\n )\n .assert_empty();\n }\n\n pub fn view(self, context: &mut PrivateContext) {\n execution_cache::store(self.args);\n context\n .call_private_function_with_args_hash(\n self.target_contract,\n self.selector,\n self.args_hash,\n true,\n )\n .assert_empty();\n }\n}\n\nimpl CallInterface for PrivateStaticCallInterface {\n fn get_args(self) -> [Field] {\n self.args\n }\n\n fn get_selector(self) -> FunctionSelector {\n self.selector\n }\n\n fn get_name(self) -> str {\n self.name\n }\n\n fn get_contract_address(self) -> AztecAddress {\n self.target_contract\n }\n\n fn get_is_static(self) -> bool {\n self.is_static\n }\n}\n\npub struct PrivateStaticCallInterface {\n pub target_contract: AztecAddress,\n pub selector: FunctionSelector,\n pub name: str,\n pub args_hash: Field,\n pub args: [Field],\n pub return_type: T,\n pub is_static: bool,\n}\n\nimpl PrivateStaticCallInterface {\n pub fn view(self, context: &mut PrivateContext) -> T\n where\n T: Deserialize,\n {\n execution_cache::store(self.args);\n let returns = context.call_private_function_with_args_hash(\n self.target_contract,\n self.selector,\n self.args_hash,\n true,\n );\n returns.get_preimage()\n }\n}\n\nimpl CallInterface for PrivateStaticVoidCallInterface {\n fn get_args(self) -> [Field] {\n self.args\n }\n\n fn get_selector(self) -> FunctionSelector {\n self.selector\n }\n\n fn get_name(self) -> str {\n self.name\n }\n\n fn get_contract_address(self) -> AztecAddress {\n self.target_contract\n }\n\n fn get_is_static(self) -> bool {\n self.is_static\n }\n}\n\npub struct PrivateStaticVoidCallInterface {\n pub target_contract: AztecAddress,\n pub selector: FunctionSelector,\n pub name: str,\n pub args_hash: Field,\n pub args: [Field],\n pub return_type: (),\n pub is_static: bool,\n}\n\nimpl PrivateStaticVoidCallInterface {\n pub fn view(self, context: &mut PrivateContext) {\n execution_cache::store(self.args);\n context\n .call_private_function_with_args_hash(\n self.target_contract,\n self.selector,\n self.args_hash,\n true,\n )\n .assert_empty();\n }\n}\n\nimpl CallInterface for PublicCallInterface {\n fn get_args(self) -> [Field] {\n self.args\n }\n\n fn get_selector(self) -> FunctionSelector {\n self.selector\n }\n\n fn get_name(self) -> str {\n self.name\n }\n\n fn get_contract_address(self) -> AztecAddress {\n self.target_contract\n }\n\n fn get_is_static(self) -> bool {\n self.is_static\n }\n}\n\npub struct PublicCallInterface {\n pub target_contract: AztecAddress,\n pub selector: FunctionSelector,\n pub name: str,\n pub args: [Field],\n pub gas_opts: GasOpts,\n pub return_type: T,\n pub is_static: bool,\n}\n\nimpl PublicCallInterface {\n pub fn with_gas(self: &mut Self, gas_opts: GasOpts) -> &mut Self {\n self.gas_opts = gas_opts;\n self\n }\n\n pub unconstrained fn call(self, context: &mut PublicContext) -> T\n where\n T: Deserialize,\n {\n let returns = context.call_public_function(\n self.target_contract,\n self.selector,\n self.args,\n self.gas_opts,\n );\n Deserialize::deserialize(returns.as_array::())\n }\n\n pub unconstrained fn view(self, context: &mut PublicContext) -> T\n where\n T: Deserialize,\n {\n let returns = context.static_call_public_function(\n self.target_contract,\n self.selector,\n self.args,\n self.gas_opts,\n );\n Deserialize::deserialize(returns.as_array::())\n }\n\n pub fn enqueue(self, context: &mut PrivateContext) {\n let args_hash = hash_args(self.args);\n execution_cache::store(self.args);\n context.call_public_function_with_args_hash(\n self.target_contract,\n self.selector,\n args_hash,\n /*static=*/\n false,\n )\n }\n\n pub fn enqueue_view(self, context: &mut PrivateContext) {\n let args_hash = hash_args(self.args);\n execution_cache::store(self.args);\n context.call_public_function_with_args_hash(\n self.target_contract,\n self.selector,\n args_hash,\n /*static=*/\n true,\n )\n }\n}\n\nimpl CallInterface for PublicVoidCallInterface {\n fn get_args(self) -> [Field] {\n self.args\n }\n\n fn get_selector(self) -> FunctionSelector {\n self.selector\n }\n\n fn get_name(self) -> str {\n self.name\n }\n\n fn get_contract_address(self) -> AztecAddress {\n self.target_contract\n }\n\n fn get_is_static(self) -> bool {\n self.is_static\n }\n}\n\npub struct PublicVoidCallInterface {\n pub target_contract: AztecAddress,\n pub selector: FunctionSelector,\n pub name: str,\n pub args: [Field],\n pub return_type: (),\n pub is_static: bool,\n pub gas_opts: GasOpts,\n}\n\nimpl PublicVoidCallInterface {\n pub fn with_gas(self: &mut Self, gas_opts: GasOpts) -> &mut Self {\n self.gas_opts = gas_opts;\n self\n }\n\n pub unconstrained fn call(self, context: &mut PublicContext) {\n let returns = context.call_public_function(\n self.target_contract,\n self.selector,\n self.args,\n self.gas_opts,\n );\n assert(returns.len() == 0);\n }\n\n pub unconstrained fn view(self, context: &mut PublicContext) {\n let returns = context.static_call_public_function(\n self.target_contract,\n self.selector,\n self.args,\n self.gas_opts,\n );\n assert(returns.len() == 0);\n }\n\n pub fn enqueue(self, context: &mut PrivateContext) {\n let args_hash = hash_args(self.args);\n execution_cache::store(self.args);\n context.call_public_function_with_args_hash(\n self.target_contract,\n self.selector,\n args_hash,\n /*static=*/\n false,\n )\n }\n\n pub fn enqueue_view(self, context: &mut PrivateContext) {\n let args_hash = hash_args(self.args);\n execution_cache::store(self.args);\n context.call_public_function_with_args_hash(\n self.target_contract,\n self.selector,\n args_hash,\n /*static=*/\n true,\n )\n }\n}\n\nimpl CallInterface for PublicStaticCallInterface {\n fn get_args(self) -> [Field] {\n self.args\n }\n\n fn get_selector(self) -> FunctionSelector {\n self.selector\n }\n\n fn get_name(self) -> str {\n self.name\n }\n\n fn get_contract_address(self) -> AztecAddress {\n self.target_contract\n }\n\n fn get_is_static(self) -> bool {\n self.is_static\n }\n}\n\npub struct PublicStaticCallInterface {\n pub target_contract: AztecAddress,\n pub selector: FunctionSelector,\n pub name: str,\n pub args: [Field],\n pub return_type: T,\n pub is_static: bool,\n pub gas_opts: GasOpts,\n}\n\nimpl PublicStaticCallInterface {\n pub fn with_gas(self: &mut Self, gas_opts: GasOpts) -> &mut Self {\n self.gas_opts = gas_opts;\n self\n }\n\n pub unconstrained fn view(self, context: &mut PublicContext) -> T\n where\n T: Deserialize,\n {\n let returns = context.static_call_public_function(\n self.target_contract,\n self.selector,\n self.args,\n self.gas_opts,\n );\n Deserialize::deserialize(returns.as_array::())\n }\n\n pub fn enqueue_view(self, context: &mut PrivateContext) {\n let args_hash = hash_args(self.args);\n execution_cache::store(self.args);\n context.call_public_function_with_args_hash(\n self.target_contract,\n self.selector,\n args_hash,\n /*static=*/\n true,\n )\n }\n}\n\nimpl CallInterface for PublicStaticVoidCallInterface {\n fn get_args(self) -> [Field] {\n self.args\n }\n\n fn get_selector(self) -> FunctionSelector {\n self.selector\n }\n\n fn get_name(self) -> str {\n self.name\n }\n\n fn get_contract_address(self) -> AztecAddress {\n self.target_contract\n }\n\n fn get_is_static(self) -> bool {\n self.is_static\n }\n}\n\npub struct PublicStaticVoidCallInterface {\n target_contract: AztecAddress,\n selector: FunctionSelector,\n name: str,\n args: [Field],\n return_type: (),\n is_static: bool,\n gas_opts: GasOpts,\n}\n\nimpl PublicStaticVoidCallInterface {\n pub fn with_gas(self: &mut Self, gas_opts: GasOpts) -> &mut Self {\n self.gas_opts = gas_opts;\n self\n }\n\n pub unconstrained fn view(self, context: &mut PublicContext) {\n let returns = context.static_call_public_function(\n self.target_contract,\n self.selector,\n self.args,\n self.gas_opts,\n );\n assert(returns.len() == 0);\n }\n\n pub fn enqueue_view(self, context: &mut PrivateContext) {\n let args_hash = hash_args(self.args);\n execution_cache::store(self.args);\n context.call_public_function_with_args_hash(\n self.target_contract,\n self.selector,\n args_hash,\n /*static=*/\n true,\n )\n }\n}\n" - }, - "70": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/context/private_context.nr", - "source": "use dep::protocol_types::debug_log::debug_log_format;\n\nuse crate::{\n context::{inputs::PrivateContextInputs, returns_hash::ReturnsHash},\n hash::{ArgsHasher, hash_args_array},\n keys::constants::{NULLIFIER_INDEX, NUM_KEY_TYPES, OUTGOING_INDEX, sk_generators},\n messaging::process_l1_to_l2_message,\n oracle::{\n block_header::get_block_header_at,\n call_private_function::call_private_function_internal,\n enqueue_public_function_call::{\n enqueue_public_function_call_internal, notify_set_min_revertible_side_effect_counter,\n set_public_teardown_function_call_internal,\n },\n execution_cache,\n key_validation_request::get_key_validation_request,\n notes::{notify_created_nullifier, notify_nullified_note},\n },\n};\nuse dep::protocol_types::{\n abis::{\n call_context::CallContext,\n function_selector::FunctionSelector,\n log::Log,\n log_hash::LogHash,\n max_block_number::MaxBlockNumber,\n note_hash::NoteHash,\n nullifier::Nullifier,\n private_call_request::PrivateCallRequest,\n private_circuit_public_inputs::PrivateCircuitPublicInputs,\n private_log::PrivateLogData,\n public_call_request::PublicCallRequest,\n read_request::ReadRequest,\n side_effect::Counted,\n validation_requests::{KeyValidationRequest, KeyValidationRequestAndGenerator},\n },\n address::{AztecAddress, EthAddress},\n block_header::BlockHeader,\n constants::{\n MAX_CONTRACT_CLASS_LOGS_PER_CALL, MAX_ENQUEUED_CALLS_PER_CALL,\n MAX_KEY_VALIDATION_REQUESTS_PER_CALL, MAX_L2_TO_L1_MSGS_PER_CALL,\n MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, MAX_NOTE_HASHES_PER_CALL,\n MAX_NULLIFIER_READ_REQUESTS_PER_CALL, MAX_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PRIVATE_LOGS_PER_CALL,\n PRIVATE_LOG_SIZE_IN_FIELDS, PUBLIC_DISPATCH_SELECTOR,\n },\n messaging::l2_to_l1_message::L2ToL1Message,\n traits::Empty,\n};\n\n// When finished, one can call .finish() to convert back to the abi\npub struct PrivateContext {\n // docs:start:private-context\n pub inputs: PrivateContextInputs,\n pub side_effect_counter: u32,\n\n pub min_revertible_side_effect_counter: u32,\n pub is_fee_payer: bool,\n\n pub args_hash: Field,\n pub return_hash: Field,\n\n pub max_block_number: MaxBlockNumber,\n\n pub note_hash_read_requests: BoundedVec,\n pub nullifier_read_requests: BoundedVec,\n key_validation_requests_and_generators: BoundedVec,\n\n pub note_hashes: BoundedVec,\n pub nullifiers: BoundedVec,\n\n pub private_call_requests: BoundedVec,\n pub public_call_requests: BoundedVec, MAX_ENQUEUED_CALLS_PER_CALL>,\n pub public_teardown_call_request: PublicCallRequest,\n pub l2_to_l1_msgs: BoundedVec,\n // docs:end:private-context\n\n // Header of a block whose state is used during private execution (not the block the transaction is included in).\n pub historical_header: BlockHeader,\n\n pub private_logs: BoundedVec,\n pub contract_class_logs_hashes: BoundedVec,\n\n // Contains the last key validation request for each key type. This is used to cache the last request and avoid\n // fetching the same request multiple times.\n // The index of the array corresponds to the key type (0 nullifier, 1 incoming, 2 outgoing, 3 tagging).\n pub last_key_validation_requests: [Option; NUM_KEY_TYPES],\n}\n\nimpl PrivateContext {\n pub fn new(inputs: PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs,\n side_effect_counter: inputs.start_side_effect_counter + 1,\n min_revertible_side_effect_counter: 0,\n is_fee_payer: false,\n args_hash,\n return_hash: 0,\n max_block_number: MaxBlockNumber::empty(),\n note_hash_read_requests: BoundedVec::new(),\n nullifier_read_requests: BoundedVec::new(),\n key_validation_requests_and_generators: BoundedVec::new(),\n note_hashes: BoundedVec::new(),\n nullifiers: BoundedVec::new(),\n historical_header: inputs.historical_header,\n private_call_requests: BoundedVec::new(),\n public_call_requests: BoundedVec::new(),\n public_teardown_call_request: PublicCallRequest::empty(),\n l2_to_l1_msgs: BoundedVec::new(),\n private_logs: BoundedVec::new(),\n contract_class_logs_hashes: BoundedVec::new(),\n last_key_validation_requests: [Option::none(); NUM_KEY_TYPES],\n }\n }\n\n pub fn msg_sender(self) -> AztecAddress {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> AztecAddress {\n self.inputs.call_context.contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.tx_context.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.tx_context.version\n }\n\n pub fn selector(self) -> FunctionSelector {\n self.inputs.call_context.function_selector\n }\n\n pub fn get_args_hash(self) -> Field {\n self.args_hash\n }\n\n pub fn push_note_hash(&mut self, note_hash: Field) {\n self.note_hashes.push(NoteHash { value: note_hash, counter: self.next_counter() });\n\n // WARNING(https://github.com/AztecProtocol/aztec-packages/issues/10558): if you delete this debug_log_format line, some tests fail.\n debug_log_format(\n \"Context.note_hashes, after pushing new note hash: {0}\",\n self.note_hashes.storage().map(|nh: NoteHash| nh.value),\n );\n }\n\n pub fn push_nullifier(&mut self, nullifier: Field) {\n notify_created_nullifier(nullifier);\n self.nullifiers.push(\n Nullifier { value: nullifier, note_hash: 0, counter: self.next_counter() },\n );\n }\n\n pub fn push_nullifier_for_note_hash(&mut self, nullifier: Field, nullified_note_hash: Field) {\n let nullifier_counter = self.next_counter();\n notify_nullified_note(nullifier, nullified_note_hash, nullifier_counter);\n self.nullifiers.push(\n Nullifier {\n value: nullifier,\n note_hash: nullified_note_hash,\n counter: nullifier_counter,\n },\n );\n }\n\n // Returns the header of a block whose state is used during private execution (not the block the transaction is\n // included in).\n pub fn get_block_header(self) -> BlockHeader {\n self.historical_header\n }\n\n // Returns the header of an arbitrary block whose block number is less than or equal to the block number\n // of historical header.\n pub fn get_block_header_at(self, block_number: u32) -> BlockHeader {\n get_block_header_at(block_number, self)\n }\n\n pub fn set_return_hash(&mut self, returns_hasher: ArgsHasher) {\n execution_cache::store(returns_hasher.fields);\n self.return_hash = returns_hasher.hash();\n }\n\n pub fn finish(self) -> PrivateCircuitPublicInputs {\n PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n returns_hash: self.return_hash,\n min_revertible_side_effect_counter: self.min_revertible_side_effect_counter,\n is_fee_payer: self.is_fee_payer,\n max_block_number: self.max_block_number,\n note_hash_read_requests: self.note_hash_read_requests.storage(),\n nullifier_read_requests: self.nullifier_read_requests.storage(),\n key_validation_requests_and_generators: self\n .key_validation_requests_and_generators\n .storage(),\n note_hashes: self.note_hashes.storage(),\n nullifiers: self.nullifiers.storage(),\n private_call_requests: self.private_call_requests.storage(),\n public_call_requests: self.public_call_requests.storage(),\n public_teardown_call_request: self.public_teardown_call_request,\n l2_to_l1_msgs: self.l2_to_l1_msgs.storage(),\n start_side_effect_counter: self.inputs.start_side_effect_counter,\n end_side_effect_counter: self.side_effect_counter,\n private_logs: self.private_logs.storage(),\n contract_class_logs_hashes: self.contract_class_logs_hashes.storage(),\n historical_header: self.historical_header,\n tx_context: self.inputs.tx_context,\n }\n }\n\n pub fn set_as_fee_payer(&mut self) {\n dep::protocol_types::debug_log::debug_log_format(\n \"Setting {0} as fee payer\",\n [self.this_address().to_field()],\n );\n self.is_fee_payer = true;\n }\n\n pub fn end_setup(&mut self) {\n // dep::protocol_types::debug_log::debug_log_format(\n // \"Ending setup at counter {0}\",\n // [self.side_effect_counter as Field]\n // );\n self.min_revertible_side_effect_counter = self.side_effect_counter;\n notify_set_min_revertible_side_effect_counter(self.min_revertible_side_effect_counter);\n }\n\n // docs:start:max-block-number\n pub fn set_tx_max_block_number(&mut self, max_block_number: u32) {\n // docs:end:max-block-number\n self.max_block_number =\n MaxBlockNumber::min_with_u32(self.max_block_number, max_block_number);\n }\n\n pub fn push_note_hash_read_request(&mut self, note_hash: Field) {\n let side_effect = ReadRequest { value: note_hash, counter: self.next_counter() };\n self.note_hash_read_requests.push(side_effect);\n }\n\n pub fn push_nullifier_read_request(&mut self, nullifier: Field) {\n let request = ReadRequest { value: nullifier, counter: self.next_counter() };\n self.nullifier_read_requests.push(request);\n }\n\n pub fn request_nsk_app(&mut self, npk_m_hash: Field) -> Field {\n self.request_sk_app(npk_m_hash, NULLIFIER_INDEX)\n }\n\n pub fn request_ovsk_app(&mut self, ovpk_m_hash: Field) -> Field {\n self.request_sk_app(ovpk_m_hash, OUTGOING_INDEX)\n }\n\n fn request_sk_app(&mut self, pk_m_hash: Field, key_index: Field) -> Field {\n let cached_request =\n self.last_key_validation_requests[key_index].unwrap_or(KeyValidationRequest::empty());\n\n if cached_request.pk_m.hash() == pk_m_hash {\n // We get a match so the cached request is the latest one\n cached_request.sk_app\n } else {\n // We didn't get a match meaning the cached result is stale\n // Typically we'd validate keys by showing that they are the preimage of `pk_m_hash`, but that'd require\n // the oracle returning the master secret keys, which could cause malicious contracts to leak it or learn\n // about secrets from other contracts. We therefore silo secret keys, and rely on the private kernel to\n // validate that we siloed secret key corresponds to correct siloing of the master secret key that hashes\n // to `pk_m_hash`.\n\n /// Safety: Kernels verify that the key validation request is valid and below we verify that a request\n /// for the correct public key has been received.\n let request = unsafe { get_key_validation_request(pk_m_hash, key_index) };\n assert_eq(request.pk_m.hash(), pk_m_hash, \"Obtained invalid key validation request\");\n\n self.key_validation_requests_and_generators.push(\n KeyValidationRequestAndGenerator {\n request,\n sk_app_generator: sk_generators[key_index],\n },\n );\n self.last_key_validation_requests[key_index] = Option::some(request);\n request.sk_app\n }\n }\n\n // docs:start:context_message_portal\n pub fn message_portal(&mut self, recipient: EthAddress, content: Field) {\n // docs:end:context_message_portal\n let message = L2ToL1Message { recipient, content, counter: self.next_counter() };\n self.l2_to_l1_msgs.push(message);\n }\n\n // docs:start:context_consume_l1_to_l2_message\n // docs:start:consume_l1_to_l2_message\n pub fn consume_l1_to_l2_message(\n &mut self,\n content: Field,\n secret: Field,\n sender: EthAddress,\n leaf_index: Field,\n ) {\n // docs:end:context_consume_l1_to_l2_message\n let nullifier = process_l1_to_l2_message(\n self.historical_header.state.l1_to_l2_message_tree.root,\n self.this_address(),\n sender,\n self.chain_id(),\n self.version(),\n content,\n secret,\n leaf_index,\n );\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_nullifier(nullifier)\n }\n // docs:end:consume_l1_to_l2_message\n\n pub fn emit_private_log(&mut self, log: [Field; PRIVATE_LOG_SIZE_IN_FIELDS]) {\n let counter = self.next_counter();\n let private_log = PrivateLogData { log: Log::new(log), note_hash_counter: 0, counter };\n self.private_logs.push(private_log);\n }\n\n pub fn emit_raw_note_log(\n &mut self,\n log: [Field; PRIVATE_LOG_SIZE_IN_FIELDS],\n note_hash_counter: u32,\n ) {\n let counter = self.next_counter();\n let private_log = PrivateLogData { log: Log::new(log), note_hash_counter, counter };\n self.private_logs.push(private_log);\n }\n\n pub fn call_private_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT],\n ) -> ReturnsHash {\n let args_hash = hash_args_array(args);\n execution_cache::store_array(args);\n self.call_private_function_with_args_hash(\n contract_address,\n function_selector,\n args_hash,\n false,\n )\n }\n\n pub fn static_call_private_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT],\n ) -> ReturnsHash {\n let args_hash = hash_args_array(args);\n execution_cache::store_array(args);\n self.call_private_function_with_args_hash(\n contract_address,\n function_selector,\n args_hash,\n true,\n )\n }\n\n pub fn call_private_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n ) -> ReturnsHash {\n self.call_private_function_with_args_hash(contract_address, function_selector, 0, false)\n }\n\n pub fn static_call_private_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n ) -> ReturnsHash {\n self.call_private_function_with_args_hash(contract_address, function_selector, 0, true)\n }\n\n pub fn call_private_function_with_args_hash(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field,\n is_static_call: bool,\n ) -> ReturnsHash {\n let mut is_static_call = is_static_call | self.inputs.call_context.is_static_call;\n let start_side_effect_counter = self.side_effect_counter;\n\n /// Safety: The oracle simulates the private call and returns the value of the side effects counter after\n /// execution of the call (which means that end_side_effect_counter - start_side_effect_counter is\n /// the number of side effects that took place), along with the hash of the return values. We validate these\n /// by requesting a private kernel iteration in which the return values are constrained to hash\n /// to `returns_hash` and the side effects counter to increment from start to end.\n let (end_side_effect_counter, returns_hash) = unsafe {\n call_private_function_internal(\n contract_address,\n function_selector,\n args_hash,\n start_side_effect_counter,\n is_static_call,\n )\n };\n\n self.private_call_requests.push(\n PrivateCallRequest {\n call_context: CallContext {\n msg_sender: self.this_address(),\n contract_address,\n function_selector,\n is_static_call,\n },\n args_hash,\n returns_hash,\n start_side_effect_counter,\n end_side_effect_counter,\n },\n );\n\n // TODO (fees) figure out why this crashes the prover and enable it\n // we need this in order to pay fees inside child call contexts\n // assert(\n // (item.public_inputs.min_revertible_side_effect_counter == 0 as u32)\n // | (item.public_inputs.min_revertible_side_effect_counter\n // > self.min_revertible_side_effect_counter)\n // );\n // if item.public_inputs.min_revertible_side_effect_counter\n // > self.min_revertible_side_effect_counter {\n // self.min_revertible_side_effect_counter = item.public_inputs.min_revertible_side_effect_counter;\n // }\n self.side_effect_counter = end_side_effect_counter + 1;\n ReturnsHash::new(returns_hash)\n }\n\n pub fn call_public_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT],\n ) {\n let args_hash = hash_args_array(args);\n execution_cache::store_array(args);\n self.call_public_function_with_args_hash(\n contract_address,\n function_selector,\n args_hash,\n false,\n )\n }\n\n pub fn static_call_public_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT],\n ) {\n let args_hash = hash_args_array(args);\n execution_cache::store_array(args);\n self.call_public_function_with_args_hash(\n contract_address,\n function_selector,\n args_hash,\n true,\n )\n }\n\n pub fn call_public_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n ) {\n self.call_public_function_with_args_hash(contract_address, function_selector, 0, false)\n }\n\n pub fn static_call_public_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n ) {\n self.call_public_function_with_args_hash(contract_address, function_selector, 0, true)\n }\n\n pub fn call_public_function_with_args_hash(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field,\n is_static_call: bool,\n ) {\n let counter = self.next_counter();\n\n let mut is_static_call = is_static_call | self.inputs.call_context.is_static_call;\n /// Safety: TODO(https://github.com/AztecProtocol/aztec-packages/issues/8985): Fix this.\n /// WARNING: This is insecure and should be temporary!\n /// The oracle hashes the arguments and returns a new args_hash.\n /// new_args = [selector, ...old_args], so as to make it suitable to call the public dispatch function.\n /// We don't validate or compute it in the circuit because a) it's harder to do with slices, and\n /// b) this is only temporary.\n let args_hash = unsafe {\n enqueue_public_function_call_internal(\n contract_address,\n function_selector,\n args_hash,\n counter,\n is_static_call,\n )\n };\n\n // Public calls are rerouted through the dispatch function.\n let function_selector = comptime { FunctionSelector::from_field(PUBLIC_DISPATCH_SELECTOR) };\n\n let call_request = PublicCallRequest {\n msg_sender: self.this_address(),\n contract_address,\n function_selector,\n is_static_call,\n args_hash,\n };\n\n self.public_call_requests.push(Counted::new(call_request, counter));\n }\n\n pub fn set_public_teardown_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT],\n ) {\n let args_hash = hash_args_array(args);\n execution_cache::store_array(args);\n self.set_public_teardown_function_with_args_hash(\n contract_address,\n function_selector,\n args_hash,\n false,\n )\n }\n\n pub fn set_public_teardown_function_with_args_hash(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field,\n is_static_call: bool,\n ) {\n let counter = self.next_counter();\n\n let mut is_static_call = is_static_call | self.inputs.call_context.is_static_call;\n /// Safety: TODO(https://github.com/AztecProtocol/aztec-packages/issues/8985): Fix this.\n /// WARNING: This is insecure and should be temporary!\n /// The oracle hashes the arguments and returns a new args_hash.\n /// new_args = [selector, ...old_args], so as to make it suitable to call the public dispatch function.\n /// We don't validate or compute it in the circuit because a) it's harder to do with slices, and\n /// b) this is only temporary.\n let args_hash = unsafe {\n set_public_teardown_function_call_internal(\n contract_address,\n function_selector,\n args_hash,\n counter,\n is_static_call,\n )\n };\n\n let function_selector = comptime { FunctionSelector::from_field(PUBLIC_DISPATCH_SELECTOR) };\n\n self.public_teardown_call_request = PublicCallRequest {\n msg_sender: self.this_address(),\n contract_address,\n function_selector,\n is_static_call,\n args_hash,\n };\n }\n\n fn next_counter(&mut self) -> u32 {\n let counter = self.side_effect_counter;\n self.side_effect_counter += 1;\n counter\n }\n}\n\nimpl Empty for PrivateContext {\n fn empty() -> Self {\n PrivateContext {\n inputs: PrivateContextInputs::empty(),\n side_effect_counter: 0 as u32,\n min_revertible_side_effect_counter: 0 as u32,\n is_fee_payer: false,\n args_hash: 0,\n return_hash: 0,\n max_block_number: MaxBlockNumber::empty(),\n note_hash_read_requests: BoundedVec::new(),\n nullifier_read_requests: BoundedVec::new(),\n key_validation_requests_and_generators: BoundedVec::new(),\n note_hashes: BoundedVec::new(),\n nullifiers: BoundedVec::new(),\n private_call_requests: BoundedVec::new(),\n public_call_requests: BoundedVec::new(),\n public_teardown_call_request: PublicCallRequest::empty(),\n l2_to_l1_msgs: BoundedVec::new(),\n historical_header: BlockHeader::empty(),\n private_logs: BoundedVec::new(),\n contract_class_logs_hashes: BoundedVec::new(),\n last_key_validation_requests: [Option::none(); NUM_KEY_TYPES],\n }\n }\n}\n" + "source": "use dep::aztec::macros::aztec;\n\n#[aztec]\ncontract SimpleLogging {\n use dep::aztec::prelude::{Map, PublicMutable};\n use dep::aztec::{\n macros::{storage::storage, functions::{public, initializer, internal}},\n };\n #[storage]\n struct Storage {\n counters: Map, Context>,\n }\n\n #[public]\n #[initializer]\n fn constructor() {\n }\n\n #[public]\n #[internal]\n fn add_to_counter_public(counter_id: Field) {\n let new_counter_value = storage.counters.at(counter_id).read() + 1;\n storage.counters.at(counter_id).write(new_counter_value);\n }\n\n #[public]\n fn increase_counter_public(counter_id: Field) {\n context.emit_public_log(/*message=*/\"pub log\");\n SimpleLogging::at(context.this_address()).add_to_counter_public(counter_id);\n }\n unconstrained fn get_counter_value(counter_id: Field) -> pub Field {\n storage.counters.at(counter_id).read()\n }\n}\n" }, "71": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/context/public_context.nr", - "source": "use crate::context::gas::GasOpts;\nuse crate::hash::{\n compute_l1_to_l2_message_hash, compute_l1_to_l2_message_nullifier, compute_secret_hash,\n};\nuse dep::protocol_types::abis::function_selector::FunctionSelector;\nuse dep::protocol_types::address::{AztecAddress, EthAddress};\nuse dep::protocol_types::constants::MAX_FIELD_VALUE;\nuse dep::protocol_types::traits::{Deserialize, Empty, Serialize};\n\npub struct PublicContext {\n pub args_hash: Option,\n pub compute_args_hash: fn() -> Field,\n}\n\nimpl PublicContext {\n pub fn new(compute_args_hash: fn() -> Field) -> Self {\n PublicContext { args_hash: Option::none(), compute_args_hash }\n }\n\n pub fn emit_unencrypted_log(_self: &mut Self, log: T)\n where\n T: Serialize,\n {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { emit_unencrypted_log(Serialize::serialize(log).as_slice()) };\n }\n\n pub fn note_hash_exists(_self: Self, note_hash: Field, leaf_index: Field) -> bool {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { note_hash_exists(note_hash, leaf_index) } == 1\n }\n\n pub fn l1_to_l2_msg_exists(_self: Self, msg_hash: Field, msg_leaf_index: Field) -> bool {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { l1_to_l2_msg_exists(msg_hash, msg_leaf_index) } == 1\n }\n\n pub fn nullifier_exists(_self: Self, unsiloed_nullifier: Field, address: AztecAddress) -> bool {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { nullifier_exists(unsiloed_nullifier, address.to_field()) } == 1\n }\n\n pub fn consume_l1_to_l2_message(\n &mut self,\n content: Field,\n secret: Field,\n sender: EthAddress,\n leaf_index: Field,\n ) {\n let secret_hash = compute_secret_hash(secret);\n let message_hash = compute_l1_to_l2_message_hash(\n sender,\n self.chain_id(),\n /*recipient=*/\n self.this_address(),\n self.version(),\n content,\n secret_hash,\n leaf_index,\n );\n let nullifier = compute_l1_to_l2_message_nullifier(message_hash, secret);\n\n assert(\n !self.nullifier_exists(nullifier, self.this_address()),\n \"L1-to-L2 message is already nullified\",\n );\n assert(\n self.l1_to_l2_msg_exists(message_hash, leaf_index),\n \"Tried to consume nonexistent L1-to-L2 message\",\n );\n\n self.push_nullifier(nullifier);\n }\n\n pub fn message_portal(_self: &mut Self, recipient: EthAddress, content: Field) {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { send_l2_to_l1_msg(recipient, content) };\n }\n\n pub unconstrained fn call_public_function(\n _self: &mut Self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field],\n gas_opts: GasOpts,\n ) -> [Field] {\n let args = args.push_front(function_selector.to_field());\n let success = call(gas_for_call(gas_opts), contract_address, args);\n\n let result_data = returndata_copy(0, returndata_size());\n if !success {\n // Rethrow the revert data.\n avm_revert(result_data);\n }\n result_data\n }\n\n pub unconstrained fn static_call_public_function(\n _self: &mut Self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field],\n gas_opts: GasOpts,\n ) -> [Field] {\n let args = args.push_front(function_selector.to_field());\n let success = call_static(gas_for_call(gas_opts), contract_address, args);\n\n let result_data = returndata_copy(0, returndata_size());\n if !success {\n // Rethrow the revert data.\n avm_revert(result_data);\n }\n result_data\n }\n\n pub fn push_note_hash(_self: &mut Self, note_hash: Field) {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { emit_note_hash(note_hash) };\n }\n pub fn push_nullifier(_self: &mut Self, nullifier: Field) {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { emit_nullifier(nullifier) };\n }\n\n pub fn this_address(_self: Self) -> AztecAddress {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n address()\n }\n }\n pub fn msg_sender(_self: Self) -> AztecAddress {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n sender()\n }\n }\n pub fn selector(_self: Self) -> FunctionSelector {\n // The selector is the first element of the calldata when calling a public function through dispatch.\n /// Safety: AVM opcodes are constrained by the AVM itself\n let raw_selector: [Field; 1] = unsafe { calldata_copy(0, 1) };\n FunctionSelector::from_field(raw_selector[0])\n }\n pub fn get_args_hash(mut self) -> Field {\n if !self.args_hash.is_some() {\n self.args_hash = Option::some((self.compute_args_hash)());\n }\n\n self.args_hash.unwrap_unchecked()\n }\n pub fn transaction_fee(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n transaction_fee()\n }\n }\n\n pub fn chain_id(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n chain_id()\n }\n }\n pub fn version(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n version()\n }\n }\n pub fn block_number(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n block_number()\n }\n }\n pub fn timestamp(_self: Self) -> u64 {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n timestamp()\n }\n }\n pub fn fee_per_l2_gas(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n fee_per_l2_gas()\n }\n }\n pub fn fee_per_da_gas(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n fee_per_da_gas()\n }\n }\n\n pub fn l2_gas_left(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n l2_gas_left()\n }\n }\n pub fn da_gas_left(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n da_gas_left()\n }\n }\n pub fn is_static_call(_self: Self) -> bool {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { is_static_call() } == 1\n }\n\n pub fn raw_storage_read(_self: Self, storage_slot: Field) -> [Field; N] {\n let mut out = [0; N];\n for i in 0..N {\n /// Safety: AVM opcodes are constrained by the AVM itself\n out[i] = unsafe { storage_read(storage_slot + i as Field) };\n }\n out\n }\n\n pub fn storage_read(self, storage_slot: Field) -> T\n where\n T: Deserialize,\n {\n T::deserialize(self.raw_storage_read(storage_slot))\n }\n\n pub fn raw_storage_write(_self: Self, storage_slot: Field, values: [Field; N]) {\n for i in 0..N {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { storage_write(storage_slot + i as Field, values[i]) };\n }\n }\n\n pub fn storage_write(self, storage_slot: Field, value: T)\n where\n T: Serialize,\n {\n self.raw_storage_write(storage_slot, value.serialize());\n }\n}\n\n// Helper functions\nfn gas_for_call(user_gas: GasOpts) -> [Field; 2] {\n // It's ok to use the max possible gas here, because the gas will be\n // capped by the gas left in the (STATIC)CALL instruction.\n [user_gas.l2_gas.unwrap_or(MAX_FIELD_VALUE), user_gas.da_gas.unwrap_or(MAX_FIELD_VALUE)]\n}\n\n// Unconstrained opcode wrappers (do not use directly).\nunconstrained fn address() -> AztecAddress {\n address_opcode()\n}\nunconstrained fn sender() -> AztecAddress {\n sender_opcode()\n}\nunconstrained fn transaction_fee() -> Field {\n transaction_fee_opcode()\n}\nunconstrained fn chain_id() -> Field {\n chain_id_opcode()\n}\nunconstrained fn version() -> Field {\n version_opcode()\n}\nunconstrained fn block_number() -> Field {\n block_number_opcode()\n}\nunconstrained fn timestamp() -> u64 {\n timestamp_opcode()\n}\nunconstrained fn fee_per_l2_gas() -> Field {\n fee_per_l2_gas_opcode()\n}\nunconstrained fn fee_per_da_gas() -> Field {\n fee_per_da_gas_opcode()\n}\nunconstrained fn l2_gas_left() -> Field {\n l2_gas_left_opcode()\n}\nunconstrained fn da_gas_left() -> Field {\n da_gas_left_opcode()\n}\nunconstrained fn is_static_call() -> Field {\n is_static_call_opcode()\n}\nunconstrained fn note_hash_exists(note_hash: Field, leaf_index: Field) -> u1 {\n note_hash_exists_opcode(note_hash, leaf_index)\n}\nunconstrained fn emit_note_hash(note_hash: Field) {\n emit_note_hash_opcode(note_hash)\n}\nunconstrained fn nullifier_exists(nullifier: Field, address: Field) -> u1 {\n nullifier_exists_opcode(nullifier, address)\n}\nunconstrained fn emit_nullifier(nullifier: Field) {\n emit_nullifier_opcode(nullifier)\n}\nunconstrained fn emit_unencrypted_log(message: [Field]) {\n emit_unencrypted_log_opcode(message)\n}\nunconstrained fn l1_to_l2_msg_exists(msg_hash: Field, msg_leaf_index: Field) -> u1 {\n l1_to_l2_msg_exists_opcode(msg_hash, msg_leaf_index)\n}\nunconstrained fn send_l2_to_l1_msg(recipient: EthAddress, content: Field) {\n send_l2_to_l1_msg_opcode(recipient, content)\n}\nunconstrained fn call(gas: [Field; 2], address: AztecAddress, args: [Field]) -> bool {\n call_opcode(gas, address, args)\n}\nunconstrained fn call_static(gas: [Field; 2], address: AztecAddress, args: [Field]) -> bool {\n call_static_opcode(gas, address, args)\n}\n\npub unconstrained fn calldata_copy(cdoffset: u32, copy_size: u32) -> [Field; N] {\n calldata_copy_opcode(cdoffset, copy_size)\n}\n\nunconstrained fn returndata_size() -> u32 {\n returndata_size_opcode()\n}\n\nunconstrained fn returndata_copy(rdoffset: u32, copy_size: u32) -> [Field] {\n returndata_copy_opcode(rdoffset, copy_size)\n}\n\npub unconstrained fn avm_return(returndata: [Field]) {\n return_opcode(returndata)\n}\n\n// This opcode reverts using the exact data given. In general it should only be used\n// to do rethrows, where the revert data is the same as the original revert data.\n// For normal reverts, use Noir's `assert` which, on top of reverting, will also add\n// an error selector to the revert data.\nunconstrained fn avm_revert(revertdata: [Field]) {\n revert_opcode(revertdata)\n}\n\nunconstrained fn storage_read(storage_slot: Field) -> Field {\n storage_read_opcode(storage_slot)\n}\n\nunconstrained fn storage_write(storage_slot: Field, value: Field) {\n storage_write_opcode(storage_slot, value);\n}\n\nimpl Empty for PublicContext {\n fn empty() -> Self {\n PublicContext::new(|| 0)\n }\n}\n\n// AVM oracles (opcodes) follow, do not use directly.\n#[oracle(avmOpcodeAddress)]\nunconstrained fn address_opcode() -> AztecAddress {}\n\n#[oracle(avmOpcodeSender)]\nunconstrained fn sender_opcode() -> AztecAddress {}\n\n#[oracle(avmOpcodeTransactionFee)]\nunconstrained fn transaction_fee_opcode() -> Field {}\n\n#[oracle(avmOpcodeChainId)]\nunconstrained fn chain_id_opcode() -> Field {}\n\n#[oracle(avmOpcodeVersion)]\nunconstrained fn version_opcode() -> Field {}\n\n#[oracle(avmOpcodeBlockNumber)]\nunconstrained fn block_number_opcode() -> Field {}\n\n#[oracle(avmOpcodeTimestamp)]\nunconstrained fn timestamp_opcode() -> u64 {}\n\n#[oracle(avmOpcodeFeePerL2Gas)]\nunconstrained fn fee_per_l2_gas_opcode() -> Field {}\n\n#[oracle(avmOpcodeFeePerDaGas)]\nunconstrained fn fee_per_da_gas_opcode() -> Field {}\n\n#[oracle(avmOpcodeL2GasLeft)]\nunconstrained fn l2_gas_left_opcode() -> Field {}\n\n#[oracle(avmOpcodeDaGasLeft)]\nunconstrained fn da_gas_left_opcode() -> Field {}\n\n#[oracle(avmOpcodeIsStaticCall)]\nunconstrained fn is_static_call_opcode() -> Field {}\n\n#[oracle(avmOpcodeNoteHashExists)]\nunconstrained fn note_hash_exists_opcode(note_hash: Field, leaf_index: Field) -> u1 {}\n\n#[oracle(avmOpcodeEmitNoteHash)]\nunconstrained fn emit_note_hash_opcode(note_hash: Field) {}\n\n#[oracle(avmOpcodeNullifierExists)]\nunconstrained fn nullifier_exists_opcode(nullifier: Field, address: Field) -> u1 {}\n\n#[oracle(avmOpcodeEmitNullifier)]\nunconstrained fn emit_nullifier_opcode(nullifier: Field) {}\n\n#[oracle(avmOpcodeEmitUnencryptedLog)]\nunconstrained fn emit_unencrypted_log_opcode(message: [Field]) {}\n\n#[oracle(avmOpcodeL1ToL2MsgExists)]\nunconstrained fn l1_to_l2_msg_exists_opcode(msg_hash: Field, msg_leaf_index: Field) -> u1 {}\n\n#[oracle(avmOpcodeSendL2ToL1Msg)]\nunconstrained fn send_l2_to_l1_msg_opcode(recipient: EthAddress, content: Field) {}\n\n#[oracle(avmOpcodeCalldataCopy)]\nunconstrained fn calldata_copy_opcode(cdoffset: u32, copy_size: u32) -> [Field; N] {}\n\n#[oracle(avmOpcodeReturndataSize)]\nunconstrained fn returndata_size_opcode() -> u32 {}\n\n#[oracle(avmOpcodeReturndataCopy)]\nunconstrained fn returndata_copy_opcode(rdoffset: u32, copy_size: u32) -> [Field] {}\n\n#[oracle(avmOpcodeReturn)]\nunconstrained fn return_opcode(returndata: [Field]) {}\n\n// This opcode reverts using the exact data given. In general it should only be used\n// to do rethrows, where the revert data is the same as the original revert data.\n// For normal reverts, use Noir's `assert` which, on top of reverting, will also add\n// an error selector to the revert data.\n#[oracle(avmOpcodeRevert)]\nunconstrained fn revert_opcode(revertdata: [Field]) {}\n\n#[oracle(avmOpcodeCall)]\nunconstrained fn call_opcode(\n gas: [Field; 2], // gas allocation: [l2_gas, da_gas]\n address: AztecAddress,\n args: [Field],\n) -> bool {}\n\n#[oracle(avmOpcodeStaticCall)]\nunconstrained fn call_static_opcode(\n gas: [Field; 2], // gas allocation: [l2_gas, da_gas]\n address: AztecAddress,\n args: [Field],\n) -> bool {}\n\n#[oracle(avmOpcodeStorageRead)]\nunconstrained fn storage_read_opcode(storage_slot: Field) -> Field {}\n\n#[oracle(avmOpcodeStorageWrite)]\nunconstrained fn storage_write_opcode(storage_slot: Field, value: Field) {}\n" + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/aztec-nr/aztec/src/context/public_context.nr", + "source": "use crate::context::gas::GasOpts;\nuse crate::hash::{\n compute_l1_to_l2_message_hash, compute_l1_to_l2_message_nullifier, compute_secret_hash,\n};\nuse dep::protocol_types::abis::function_selector::FunctionSelector;\nuse dep::protocol_types::address::{AztecAddress, EthAddress};\nuse dep::protocol_types::constants::MAX_FIELD_VALUE;\nuse dep::protocol_types::traits::{Empty, Packable, Serialize};\n\npub struct PublicContext {\n pub args_hash: Option,\n pub compute_args_hash: fn() -> Field,\n}\n\nimpl PublicContext {\n pub fn new(compute_args_hash: fn() -> Field) -> Self {\n PublicContext { args_hash: Option::none(), compute_args_hash }\n }\n\n pub fn emit_public_log(_self: &mut Self, log: T)\n where\n T: Serialize,\n {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { emit_public_log(Serialize::serialize(log).as_slice()) };\n }\n\n pub fn note_hash_exists(_self: Self, note_hash: Field, leaf_index: Field) -> bool {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { note_hash_exists(note_hash, leaf_index) } == 1\n }\n\n pub fn l1_to_l2_msg_exists(_self: Self, msg_hash: Field, msg_leaf_index: Field) -> bool {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { l1_to_l2_msg_exists(msg_hash, msg_leaf_index) } == 1\n }\n\n pub fn nullifier_exists(_self: Self, unsiloed_nullifier: Field, address: AztecAddress) -> bool {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { nullifier_exists(unsiloed_nullifier, address.to_field()) } == 1\n }\n\n pub fn consume_l1_to_l2_message(\n &mut self,\n content: Field,\n secret: Field,\n sender: EthAddress,\n leaf_index: Field,\n ) {\n let secret_hash = compute_secret_hash(secret);\n let message_hash = compute_l1_to_l2_message_hash(\n sender,\n self.chain_id(),\n /*recipient=*/\n self.this_address(),\n self.version(),\n content,\n secret_hash,\n leaf_index,\n );\n let nullifier = compute_l1_to_l2_message_nullifier(message_hash, secret);\n\n assert(\n !self.nullifier_exists(nullifier, self.this_address()),\n \"L1-to-L2 message is already nullified\",\n );\n assert(\n self.l1_to_l2_msg_exists(message_hash, leaf_index),\n \"Tried to consume nonexistent L1-to-L2 message\",\n );\n\n self.push_nullifier(nullifier);\n }\n\n pub fn message_portal(_self: &mut Self, recipient: EthAddress, content: Field) {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { send_l2_to_l1_msg(recipient, content) };\n }\n\n pub unconstrained fn call_public_function(\n _self: &mut Self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field],\n gas_opts: GasOpts,\n ) -> [Field] {\n let args = args.push_front(function_selector.to_field());\n let success = call(gas_for_call(gas_opts), contract_address, args);\n\n let result_data = returndata_copy(0, returndata_size());\n if !success {\n // Rethrow the revert data.\n avm_revert(result_data);\n }\n result_data\n }\n\n pub unconstrained fn static_call_public_function(\n _self: &mut Self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field],\n gas_opts: GasOpts,\n ) -> [Field] {\n let args = args.push_front(function_selector.to_field());\n let success = call_static(gas_for_call(gas_opts), contract_address, args);\n\n let result_data = returndata_copy(0, returndata_size());\n if !success {\n // Rethrow the revert data.\n avm_revert(result_data);\n }\n result_data\n }\n\n pub fn push_note_hash(_self: &mut Self, note_hash: Field) {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { emit_note_hash(note_hash) };\n }\n pub fn push_nullifier(_self: &mut Self, nullifier: Field) {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { emit_nullifier(nullifier) };\n }\n\n pub fn this_address(_self: Self) -> AztecAddress {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n address()\n }\n }\n pub fn msg_sender(_self: Self) -> AztecAddress {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n sender()\n }\n }\n pub fn selector(_self: Self) -> FunctionSelector {\n // The selector is the first element of the calldata when calling a public function through dispatch.\n /// Safety: AVM opcodes are constrained by the AVM itself\n let raw_selector: [Field; 1] = unsafe { calldata_copy(0, 1) };\n FunctionSelector::from_field(raw_selector[0])\n }\n pub fn get_args_hash(mut self) -> Field {\n if !self.args_hash.is_some() {\n self.args_hash = Option::some((self.compute_args_hash)());\n }\n\n self.args_hash.unwrap_unchecked()\n }\n pub fn transaction_fee(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n transaction_fee()\n }\n }\n\n pub fn chain_id(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n chain_id()\n }\n }\n pub fn version(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n version()\n }\n }\n pub fn block_number(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n block_number()\n }\n }\n pub fn timestamp(_self: Self) -> u64 {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n timestamp()\n }\n }\n pub fn fee_per_l2_gas(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n fee_per_l2_gas()\n }\n }\n pub fn fee_per_da_gas(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n fee_per_da_gas()\n }\n }\n\n pub fn l2_gas_left(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n l2_gas_left()\n }\n }\n pub fn da_gas_left(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n da_gas_left()\n }\n }\n pub fn is_static_call(_self: Self) -> bool {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { is_static_call() } == 1\n }\n\n pub fn raw_storage_read(_self: Self, storage_slot: Field) -> [Field; N] {\n let mut out = [0; N];\n for i in 0..N {\n /// Safety: AVM opcodes are constrained by the AVM itself\n out[i] = unsafe { storage_read(storage_slot + i as Field) };\n }\n out\n }\n\n pub fn storage_read(self, storage_slot: Field) -> T\n where\n T: Packable,\n {\n T::unpack(self.raw_storage_read(storage_slot))\n }\n\n pub fn raw_storage_write(_self: Self, storage_slot: Field, values: [Field; N]) {\n for i in 0..N {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { storage_write(storage_slot + i as Field, values[i]) };\n }\n }\n\n pub fn storage_write(self, storage_slot: Field, value: T)\n where\n T: Packable,\n {\n self.raw_storage_write(storage_slot, value.pack());\n }\n}\n\n// Helper functions\nfn gas_for_call(user_gas: GasOpts) -> [Field; 2] {\n // It's ok to use the max possible gas here, because the gas will be\n // capped by the gas left in the (STATIC)CALL instruction.\n [user_gas.l2_gas.unwrap_or(MAX_FIELD_VALUE), user_gas.da_gas.unwrap_or(MAX_FIELD_VALUE)]\n}\n\n// Unconstrained opcode wrappers (do not use directly).\nunconstrained fn address() -> AztecAddress {\n address_opcode()\n}\nunconstrained fn sender() -> AztecAddress {\n sender_opcode()\n}\nunconstrained fn transaction_fee() -> Field {\n transaction_fee_opcode()\n}\nunconstrained fn chain_id() -> Field {\n chain_id_opcode()\n}\nunconstrained fn version() -> Field {\n version_opcode()\n}\nunconstrained fn block_number() -> Field {\n block_number_opcode()\n}\nunconstrained fn timestamp() -> u64 {\n timestamp_opcode()\n}\nunconstrained fn fee_per_l2_gas() -> Field {\n fee_per_l2_gas_opcode()\n}\nunconstrained fn fee_per_da_gas() -> Field {\n fee_per_da_gas_opcode()\n}\nunconstrained fn l2_gas_left() -> Field {\n l2_gas_left_opcode()\n}\nunconstrained fn da_gas_left() -> Field {\n da_gas_left_opcode()\n}\nunconstrained fn is_static_call() -> Field {\n is_static_call_opcode()\n}\nunconstrained fn note_hash_exists(note_hash: Field, leaf_index: Field) -> u1 {\n note_hash_exists_opcode(note_hash, leaf_index)\n}\nunconstrained fn emit_note_hash(note_hash: Field) {\n emit_note_hash_opcode(note_hash)\n}\nunconstrained fn nullifier_exists(nullifier: Field, address: Field) -> u1 {\n nullifier_exists_opcode(nullifier, address)\n}\nunconstrained fn emit_nullifier(nullifier: Field) {\n emit_nullifier_opcode(nullifier)\n}\nunconstrained fn emit_public_log(message: [Field]) {\n emit_public_log_opcode(message)\n}\nunconstrained fn l1_to_l2_msg_exists(msg_hash: Field, msg_leaf_index: Field) -> u1 {\n l1_to_l2_msg_exists_opcode(msg_hash, msg_leaf_index)\n}\nunconstrained fn send_l2_to_l1_msg(recipient: EthAddress, content: Field) {\n send_l2_to_l1_msg_opcode(recipient, content)\n}\nunconstrained fn call(gas: [Field; 2], address: AztecAddress, args: [Field]) -> bool {\n call_opcode(gas, address, args)\n}\nunconstrained fn call_static(gas: [Field; 2], address: AztecAddress, args: [Field]) -> bool {\n call_static_opcode(gas, address, args)\n}\n\npub unconstrained fn calldata_copy(cdoffset: u32, copy_size: u32) -> [Field; N] {\n calldata_copy_opcode(cdoffset, copy_size)\n}\n\nunconstrained fn returndata_size() -> u32 {\n returndata_size_opcode()\n}\n\nunconstrained fn returndata_copy(rdoffset: u32, copy_size: u32) -> [Field] {\n returndata_copy_opcode(rdoffset, copy_size)\n}\n\npub unconstrained fn avm_return(returndata: [Field]) {\n return_opcode(returndata)\n}\n\n// This opcode reverts using the exact data given. In general it should only be used\n// to do rethrows, where the revert data is the same as the original revert data.\n// For normal reverts, use Noir's `assert` which, on top of reverting, will also add\n// an error selector to the revert data.\nunconstrained fn avm_revert(revertdata: [Field]) {\n revert_opcode(revertdata)\n}\n\nunconstrained fn storage_read(storage_slot: Field) -> Field {\n storage_read_opcode(storage_slot)\n}\n\nunconstrained fn storage_write(storage_slot: Field, value: Field) {\n storage_write_opcode(storage_slot, value);\n}\n\nimpl Empty for PublicContext {\n fn empty() -> Self {\n PublicContext::new(|| 0)\n }\n}\n\n// AVM oracles (opcodes) follow, do not use directly.\n#[oracle(avmOpcodeAddress)]\nunconstrained fn address_opcode() -> AztecAddress {}\n\n#[oracle(avmOpcodeSender)]\nunconstrained fn sender_opcode() -> AztecAddress {}\n\n#[oracle(avmOpcodeTransactionFee)]\nunconstrained fn transaction_fee_opcode() -> Field {}\n\n#[oracle(avmOpcodeChainId)]\nunconstrained fn chain_id_opcode() -> Field {}\n\n#[oracle(avmOpcodeVersion)]\nunconstrained fn version_opcode() -> Field {}\n\n#[oracle(avmOpcodeBlockNumber)]\nunconstrained fn block_number_opcode() -> Field {}\n\n#[oracle(avmOpcodeTimestamp)]\nunconstrained fn timestamp_opcode() -> u64 {}\n\n#[oracle(avmOpcodeFeePerL2Gas)]\nunconstrained fn fee_per_l2_gas_opcode() -> Field {}\n\n#[oracle(avmOpcodeFeePerDaGas)]\nunconstrained fn fee_per_da_gas_opcode() -> Field {}\n\n#[oracle(avmOpcodeL2GasLeft)]\nunconstrained fn l2_gas_left_opcode() -> Field {}\n\n#[oracle(avmOpcodeDaGasLeft)]\nunconstrained fn da_gas_left_opcode() -> Field {}\n\n#[oracle(avmOpcodeIsStaticCall)]\nunconstrained fn is_static_call_opcode() -> Field {}\n\n#[oracle(avmOpcodeNoteHashExists)]\nunconstrained fn note_hash_exists_opcode(note_hash: Field, leaf_index: Field) -> u1 {}\n\n#[oracle(avmOpcodeEmitNoteHash)]\nunconstrained fn emit_note_hash_opcode(note_hash: Field) {}\n\n#[oracle(avmOpcodeNullifierExists)]\nunconstrained fn nullifier_exists_opcode(nullifier: Field, address: Field) -> u1 {}\n\n#[oracle(avmOpcodeEmitNullifier)]\nunconstrained fn emit_nullifier_opcode(nullifier: Field) {}\n\n// TODO(#11124): rename unencrypted to public in avm\n#[oracle(avmOpcodeEmitUnencryptedLog)]\nunconstrained fn emit_public_log_opcode(message: [Field]) {}\n\n#[oracle(avmOpcodeL1ToL2MsgExists)]\nunconstrained fn l1_to_l2_msg_exists_opcode(msg_hash: Field, msg_leaf_index: Field) -> u1 {}\n\n#[oracle(avmOpcodeSendL2ToL1Msg)]\nunconstrained fn send_l2_to_l1_msg_opcode(recipient: EthAddress, content: Field) {}\n\n#[oracle(avmOpcodeCalldataCopy)]\nunconstrained fn calldata_copy_opcode(cdoffset: u32, copy_size: u32) -> [Field; N] {}\n\n#[oracle(avmOpcodeReturndataSize)]\nunconstrained fn returndata_size_opcode() -> u32 {}\n\n#[oracle(avmOpcodeReturndataCopy)]\nunconstrained fn returndata_copy_opcode(rdoffset: u32, copy_size: u32) -> [Field] {}\n\n#[oracle(avmOpcodeReturn)]\nunconstrained fn return_opcode(returndata: [Field]) {}\n\n// This opcode reverts using the exact data given. In general it should only be used\n// to do rethrows, where the revert data is the same as the original revert data.\n// For normal reverts, use Noir's `assert` which, on top of reverting, will also add\n// an error selector to the revert data.\n#[oracle(avmOpcodeRevert)]\nunconstrained fn revert_opcode(revertdata: [Field]) {}\n\n#[oracle(avmOpcodeCall)]\nunconstrained fn call_opcode(\n gas: [Field; 2], // gas allocation: [l2_gas, da_gas]\n address: AztecAddress,\n args: [Field],\n) -> bool {}\n\n#[oracle(avmOpcodeStaticCall)]\nunconstrained fn call_static_opcode(\n gas: [Field; 2], // gas allocation: [l2_gas, da_gas]\n address: AztecAddress,\n args: [Field],\n) -> bool {}\n\n#[oracle(avmOpcodeStorageRead)]\nunconstrained fn storage_read_opcode(storage_slot: Field) -> Field {}\n\n#[oracle(avmOpcodeStorageWrite)]\nunconstrained fn storage_write_opcode(storage_slot: Field, value: Field) {}\n" }, "73": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/context/unconstrained_context.nr", - "source": "use crate::oracle::{\n execution::{get_block_number, get_chain_id, get_contract_address, get_version},\n storage::storage_read,\n};\nuse dep::protocol_types::{address::AztecAddress, traits::Deserialize};\n\npub struct UnconstrainedContext {\n block_number: u32,\n contract_address: AztecAddress,\n version: Field,\n chain_id: Field,\n}\n\nimpl UnconstrainedContext {\n pub unconstrained fn new() -> Self {\n // We could call these oracles on the getters instead of at creation, which makes sense given that they might\n // not even be accessed. However any performance gains are minimal, and we'd rather fail early if a user\n // incorrectly attempts to create an UnconstrainedContext in an environment in which these oracles are not\n // available.\n let block_number = get_block_number();\n let contract_address = get_contract_address();\n let chain_id = get_chain_id();\n let version = get_version();\n Self { block_number, contract_address, version, chain_id }\n }\n\n pub unconstrained fn at(contract_address: AztecAddress) -> Self {\n let block_number = get_block_number();\n let chain_id = get_chain_id();\n let version = get_version();\n Self { block_number, contract_address, version, chain_id }\n }\n\n pub unconstrained fn at_historical(contract_address: AztecAddress, block_number: u32) -> Self {\n let chain_id = get_chain_id();\n let version = get_version();\n Self { block_number, contract_address, version, chain_id }\n }\n\n pub fn block_number(self) -> u32 {\n self.block_number\n }\n\n pub fn this_address(self) -> AztecAddress {\n self.contract_address\n }\n\n pub fn version(self) -> Field {\n self.version\n }\n\n pub fn chain_id(self) -> Field {\n self.chain_id\n }\n\n pub unconstrained fn raw_storage_read(\n self: Self,\n storage_slot: Field,\n ) -> [Field; N] {\n storage_read(self.this_address(), storage_slot, self.block_number())\n }\n\n pub unconstrained fn storage_read(self, storage_slot: Field) -> T\n where\n T: Deserialize,\n {\n T::deserialize(self.raw_storage_read(storage_slot))\n }\n}\n" - }, - "83": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/hash.nr", - "source": "use crate::utils::to_bytes::{arr_to_be_bytes_arr, str_to_be_bytes_arr};\nuse dep::protocol_types::{\n address::{AztecAddress, EthAddress},\n constants::{\n GENERATOR_INDEX__FUNCTION_ARGS, GENERATOR_INDEX__MESSAGE_NULLIFIER,\n GENERATOR_INDEX__SECRET_HASH,\n },\n hash::{poseidon2_hash_with_separator, poseidon2_hash_with_separator_slice, sha256_to_field},\n point::Point,\n traits::Hash,\n};\n\npub use dep::protocol_types::hash::{compute_siloed_nullifier, pedersen_hash};\n\npub fn pedersen_commitment(inputs: [Field; N], hash_index: u32) -> Point {\n std::hash::pedersen_commitment_with_separator(inputs, hash_index)\n}\n\npub fn compute_secret_hash(secret: Field) -> Field {\n poseidon2_hash_with_separator([secret], GENERATOR_INDEX__SECRET_HASH)\n}\n\npub fn compute_unencrypted_log_hash(\n contract_address: AztecAddress,\n log: [u8; N],\n) -> Field {\n let mut hash_bytes = [0; N + 36];\n // Address is converted to 32 bytes in ts\n let address_bytes: [u8; 32] = contract_address.to_field().to_be_bytes();\n for i in 0..32 {\n hash_bytes[i] = address_bytes[i];\n }\n let len_bytes: [u8; 4] = (N as Field).to_be_bytes();\n for i in 0..4 {\n hash_bytes[32 + i] = len_bytes[i];\n }\n for i in 0..N {\n hash_bytes[36 + i] = log[i];\n }\n\n sha256_to_field(hash_bytes)\n}\n\npub fn compute_l1_to_l2_message_hash(\n sender: EthAddress,\n chain_id: Field,\n recipient: AztecAddress,\n version: Field,\n content: Field,\n secret_hash: Field,\n leaf_index: Field,\n) -> Field {\n let mut hash_bytes = [0 as u8; 224];\n let sender_bytes: [u8; 32] = sender.to_field().to_be_bytes();\n let chain_id_bytes: [u8; 32] = chain_id.to_be_bytes();\n let recipient_bytes: [u8; 32] = recipient.to_field().to_be_bytes();\n let version_bytes: [u8; 32] = version.to_be_bytes();\n let content_bytes: [u8; 32] = content.to_be_bytes();\n let secret_hash_bytes: [u8; 32] = secret_hash.to_be_bytes();\n let leaf_index_bytes: [u8; 32] = leaf_index.to_be_bytes();\n\n for i in 0..32 {\n hash_bytes[i] = sender_bytes[i];\n hash_bytes[i + 32] = chain_id_bytes[i];\n hash_bytes[i + 64] = recipient_bytes[i];\n hash_bytes[i + 96] = version_bytes[i];\n hash_bytes[i + 128] = content_bytes[i];\n hash_bytes[i + 160] = secret_hash_bytes[i];\n hash_bytes[i + 192] = leaf_index_bytes[i];\n }\n\n sha256_to_field(hash_bytes)\n}\n\n// The nullifier of a l1 to l2 message is the hash of the message salted with the secret\npub fn compute_l1_to_l2_message_nullifier(message_hash: Field, secret: Field) -> Field {\n poseidon2_hash_with_separator([message_hash, secret], GENERATOR_INDEX__MESSAGE_NULLIFIER)\n}\n\npub struct ArgsHasher {\n pub fields: [Field],\n}\n\nimpl Hash for ArgsHasher {\n fn hash(self) -> Field {\n hash_args(self.fields)\n }\n}\n\nimpl ArgsHasher {\n pub fn new() -> Self {\n Self { fields: [] }\n }\n\n pub fn add(&mut self, field: Field) {\n self.fields = self.fields.push_back(field);\n }\n\n pub fn add_multiple(&mut self, fields: [Field; N]) {\n for i in 0..N {\n self.fields = self.fields.push_back(fields[i]);\n }\n }\n}\n\npub fn hash_args_array(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n poseidon2_hash_with_separator(args, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n\npub fn hash_args(args: [Field]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n poseidon2_hash_with_separator_slice(args, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n\n#[test]\nunconstrained fn compute_var_args_hash() {\n let mut input = ArgsHasher::new();\n for i in 0..100 {\n input.add(i as Field);\n }\n let hash = input.hash();\n dep::std::println(hash);\n assert(hash == 0x19b0d74feb06ebde19edd85a28986c97063e84b3b351a8b666c7cac963ce655f);\n}\n\n#[test]\nunconstrained fn compute_unenc_log_hash_array() {\n let contract_address = AztecAddress::from_field(\n 0x233a3e0df23b2b15b324194cb4a151f26c0b7333250781d34cc269d85dc334c6,\n );\n let log = [\n 0x20660de09f35f876e3e69d227b2a35166ad05f09d82d06366ec9b6f65a51fec2,\n 0x1b52bfe3b8689761916f76dc3d38aa8810860db325cd39ca611eed980091f01c,\n 0x2e559c4045c378a56ad13b9edb1e8de4e7ad3b3aa35cc7ba9ec77f7a68fa43a4,\n 0x25d0f689c4a4178a29d59306f2675824d19be6d25e44fa03b03f49c263053dd2,\n 0x2d513a722d6f352dc0961f156afdc5e31495b9f0e35cb069261a8e55e2df67fd,\n ];\n let serialized_log = arr_to_be_bytes_arr(log);\n let hash = compute_unencrypted_log_hash(contract_address, serialized_log);\n assert(hash == 0x0095b2d17ab72f4b27a341f7ac63e49ec73935ae8c9181a0ac02023eb12f3284);\n}\n\n#[test]\nunconstrained fn compute_unenc_log_hash_addr() {\n let contract_address = AztecAddress::from_field(\n 0x233a3e0df23b2b15b324194cb4a151f26c0b7333250781d34cc269d85dc334c6,\n );\n let log = AztecAddress::from_field(\n 0x26aa302d4715fd8a687453cb26d616b0768027bd54bcae56b09d908ecd9f8303,\n );\n let serialized_log: [u8; 32] = log.to_field().to_be_bytes();\n let hash = compute_unencrypted_log_hash(contract_address, serialized_log);\n assert(hash == 0x0083ab647dfb26e7ddee90a0f4209d049d4660cab42000c544b986aaa84c55a3);\n}\n\n#[test]\nunconstrained fn compute_unenc_log_hash_str() {\n let contract_address = AztecAddress::from_field(\n 0x1b401e1146c5c507962287065c81f0ef7590adae3802c533d7549d6bf0a41bd8,\n );\n let log = \"dummy\";\n let serialized_log = str_to_be_bytes_arr(log);\n let hash = compute_unencrypted_log_hash(contract_address, serialized_log);\n assert(hash == 0x00629e88ebd6374f44aa6cfe07e251ecf07213ebc7267e8f6b578ae57ffd6c20);\n}\n\n#[test]\nunconstrained fn compute_unenc_log_hash_longer_str() {\n let contract_address = AztecAddress::from_field(\n 0x1b401e1146c5c507962287065c81f0ef7590adae3802c533d7549d6bf0a41bd8,\n );\n let log = \"Hello this is a string\";\n let serialized_log = str_to_be_bytes_arr(log);\n let hash = compute_unencrypted_log_hash(contract_address, serialized_log);\n assert(hash == 0x0098637962f7d34fa202b7ffad8a07a238c5d1fd897b82a108f7f467fa73b841);\n}\n" + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/aztec-nr/aztec/src/context/unconstrained_context.nr", + "source": "use crate::oracle::{\n execution::{get_block_number, get_chain_id, get_contract_address, get_version},\n storage::storage_read,\n};\nuse dep::protocol_types::{address::AztecAddress, traits::Packable};\n\npub struct UnconstrainedContext {\n block_number: u32,\n contract_address: AztecAddress,\n version: Field,\n chain_id: Field,\n}\n\nimpl UnconstrainedContext {\n pub unconstrained fn new() -> Self {\n // We could call these oracles on the getters instead of at creation, which makes sense given that they might\n // not even be accessed. However any performance gains are minimal, and we'd rather fail early if a user\n // incorrectly attempts to create an UnconstrainedContext in an environment in which these oracles are not\n // available.\n let block_number = get_block_number();\n let contract_address = get_contract_address();\n let chain_id = get_chain_id();\n let version = get_version();\n Self { block_number, contract_address, version, chain_id }\n }\n\n pub unconstrained fn at(contract_address: AztecAddress) -> Self {\n let block_number = get_block_number();\n let chain_id = get_chain_id();\n let version = get_version();\n Self { block_number, contract_address, version, chain_id }\n }\n\n pub unconstrained fn at_historical(contract_address: AztecAddress, block_number: u32) -> Self {\n let chain_id = get_chain_id();\n let version = get_version();\n Self { block_number, contract_address, version, chain_id }\n }\n\n pub fn block_number(self) -> u32 {\n self.block_number\n }\n\n pub fn this_address(self) -> AztecAddress {\n self.contract_address\n }\n\n pub fn version(self) -> Field {\n self.version\n }\n\n pub fn chain_id(self) -> Field {\n self.chain_id\n }\n\n pub unconstrained fn raw_storage_read(\n self: Self,\n storage_slot: Field,\n ) -> [Field; N] {\n storage_read(self.this_address(), storage_slot, self.block_number())\n }\n\n pub unconstrained fn storage_read(self, storage_slot: Field) -> T\n where\n T: Packable,\n {\n T::unpack(self.raw_storage_read(storage_slot))\n }\n}\n" }, "99": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/macros/functions/initialization_utils.nr", - "source": "use dep::protocol_types::{\n abis::function_selector::FunctionSelector, address::AztecAddress,\n constants::GENERATOR_INDEX__CONSTRUCTOR, hash::poseidon2_hash_with_separator,\n};\n\nuse crate::{\n context::{PrivateContext, PublicContext},\n oracle::get_contract_instance::{\n get_contract_instance, get_contract_instance_deployer_avm,\n get_contract_instance_initialization_hash_avm,\n },\n};\n\npub fn mark_as_initialized_public(context: &mut PublicContext) {\n let init_nullifier =\n compute_unsiloed_contract_initialization_nullifier((*context).this_address());\n context.push_nullifier(init_nullifier);\n}\n\npub fn mark_as_initialized_private(context: &mut PrivateContext) {\n let init_nullifier =\n compute_unsiloed_contract_initialization_nullifier((*context).this_address());\n context.push_nullifier(init_nullifier);\n}\n\npub fn assert_is_initialized_public(context: &mut PublicContext) {\n let init_nullifier = compute_unsiloed_contract_initialization_nullifier(context.this_address());\n assert(context.nullifier_exists(init_nullifier, context.this_address()), \"Not initialized\");\n}\n\npub fn assert_is_initialized_private(context: &mut PrivateContext) {\n let init_nullifier = compute_unsiloed_contract_initialization_nullifier(context.this_address());\n context.push_nullifier_read_request(init_nullifier);\n}\n\nfn compute_unsiloed_contract_initialization_nullifier(address: AztecAddress) -> Field {\n address.to_field()\n}\n\npub fn assert_initialization_matches_address_preimage_public(context: PublicContext) {\n let address = context.this_address();\n let deployer = get_contract_instance_deployer_avm(address).unwrap();\n let initialization_hash = get_contract_instance_initialization_hash_avm(address).unwrap();\n let expected_init = compute_initialization_hash(context.selector(), context.get_args_hash());\n assert(initialization_hash == expected_init, \"Initialization hash does not match\");\n assert(\n (deployer.is_zero()) | (deployer == context.msg_sender()),\n \"Initializer address is not the contract deployer\",\n );\n}\n\npub fn assert_initialization_matches_address_preimage_private(context: PrivateContext) {\n let address = context.this_address();\n let instance = get_contract_instance(address);\n let expected_init = compute_initialization_hash(context.selector(), context.get_args_hash());\n assert(instance.initialization_hash == expected_init, \"Initialization hash does not match\");\n assert(\n (instance.deployer.is_zero()) | (instance.deployer == context.msg_sender()),\n \"Initializer address is not the contract deployer\",\n );\n}\n\nfn compute_initialization_hash(init_selector: FunctionSelector, init_args_hash: Field) -> Field {\n poseidon2_hash_with_separator(\n [init_selector.to_field(), init_args_hash],\n GENERATOR_INDEX__CONSTRUCTOR,\n )\n}\n" + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/aztec-nr/aztec/src/macros/functions/initialization_utils.nr", + "source": "use dep::protocol_types::{\n abis::function_selector::FunctionSelector, address::AztecAddress,\n constants::GENERATOR_INDEX__CONSTRUCTOR, hash::poseidon2_hash_with_separator,\n};\n\nuse crate::{\n context::{PrivateContext, PublicContext},\n oracle::get_contract_instance::{\n get_contract_instance, get_contract_instance_deployer_avm,\n get_contract_instance_initialization_hash_avm,\n },\n};\n\npub fn mark_as_initialized_public(context: &mut PublicContext) {\n let init_nullifier =\n compute_unsiloed_contract_initialization_nullifier((*context).this_address());\n context.push_nullifier(init_nullifier);\n}\n\npub fn mark_as_initialized_private(context: &mut PrivateContext) {\n let init_nullifier =\n compute_unsiloed_contract_initialization_nullifier((*context).this_address());\n context.push_nullifier(init_nullifier);\n}\n\npub fn assert_is_initialized_public(context: &mut PublicContext) {\n let init_nullifier = compute_unsiloed_contract_initialization_nullifier(context.this_address());\n assert(context.nullifier_exists(init_nullifier, context.this_address()), \"Not initialized\");\n}\n\npub fn assert_is_initialized_private(context: &mut PrivateContext) {\n let init_nullifier = compute_unsiloed_contract_initialization_nullifier(context.this_address());\n context.push_nullifier_read_request(init_nullifier);\n}\n\nfn compute_unsiloed_contract_initialization_nullifier(address: AztecAddress) -> Field {\n address.to_field()\n}\n\npub fn assert_initialization_matches_address_preimage_public(context: PublicContext) {\n let address = context.this_address();\n let deployer = get_contract_instance_deployer_avm(address).unwrap();\n let initialization_hash = get_contract_instance_initialization_hash_avm(address).unwrap();\n let expected_init = compute_initialization_hash(context.selector(), context.get_args_hash());\n assert(initialization_hash == expected_init, \"Initialization hash does not match\");\n assert(\n (deployer.is_zero()) | (deployer == context.msg_sender()),\n \"Initializer address is not the contract deployer\",\n );\n}\n\npub fn assert_initialization_matches_address_preimage_private(context: PrivateContext) {\n let address = context.this_address();\n let instance = get_contract_instance(address);\n let expected_init = compute_initialization_hash(context.selector(), context.get_args_hash());\n assert(instance.initialization_hash == expected_init, \"Initialization hash does not match\");\n assert(\n (instance.deployer.is_zero()) | (instance.deployer == context.msg_sender()),\n \"Initializer address is not the contract deployer\",\n );\n}\n\n/// This function is not only used in macros but it's also used by external people to check that an instance has been\n/// initialized with the correct constructor arguments. Don't hide this unless you implement factory functionality.\npub fn compute_initialization_hash(\n init_selector: FunctionSelector,\n init_args_hash: Field,\n) -> Field {\n poseidon2_hash_with_separator(\n [init_selector.to_field(), init_args_hash],\n GENERATOR_INDEX__CONSTRUCTOR,\n )\n}\n" } } } diff --git a/services/event-cannon/src/contract-projects/SimpleLogging/target/simple_logging-SimpleLogging.json.bak b/services/event-cannon/src/contract-projects/SimpleLogging/target/simple_logging-SimpleLogging.json.bak index 175b44b5d..77c85a120 100644 --- a/services/event-cannon/src/contract-projects/SimpleLogging/target/simple_logging-SimpleLogging.json.bak +++ b/services/event-cannon/src/contract-projects/SimpleLogging/target/simple_logging-SimpleLogging.json.bak @@ -1 +1 @@ -{"noir_version":"1.0.0-beta.1+2d73c1d7bc5b1db7","name":"SimpleLogging","functions":[{"name":"process_log","is_unconstrained":true,"custom_attributes":[],"abi":{"parameters":[{"name":"log_plaintext","type":{"kind":"struct","path":"std::collections::bounded_vec::BoundedVec","fields":[{"name":"storage","type":{"kind":"array","length":18,"type":{"kind":"field"}}},{"name":"len","type":{"kind":"integer","sign":"unsigned","width":32}}]},"visibility":"private"},{"name":"tx_hash","type":{"kind":"field"},"visibility":"private"},{"name":"unique_note_hashes_in_tx","type":{"kind":"struct","path":"std::collections::bounded_vec::BoundedVec","fields":[{"name":"storage","type":{"kind":"array","length":64,"type":{"kind":"field"}}},{"name":"len","type":{"kind":"integer","sign":"unsigned","width":32}}]},"visibility":"private"},{"name":"first_nullifier_in_tx","type":{"kind":"field"},"visibility":"private"},{"name":"recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::aztec_address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"return_type":null,"error_types":{"16541607464495309456":{"error_kind":"fmtstring","length":16,"item_types":[]},"17843811134343075018":{"error_kind":"string","string":"Stack too deep"}}},"bytecode":"H4sIAAAAAAAA/92caVPbMBCGHbABB0LC0fukNy1tHZKQpCctve8L+jlTyJ9oP7j9E7T/tnlBSzZCnaGDNOWtZzxOvMruo7Usr6VVCtH2ttbbC+ZzbI6j5ojz09HgJmWXzTHb31b1qCsLxVggYBwiYBwmYIwJGBMCxhECxlECxjECxpSAsUjAOE7AOEHAWCJgnCRgLBMwVggYpwIwhuCcJuGc8cipY/tQvLPRwW+jhwgYDxMwHiFgPErAeIyA8TgB4wkCxpMEjKcIGE8TMJ4hYDxLwDhHwHiOgPE8AeMFAsaLBIyXCBgvEzBeIWCcJ2C8SsB4jYBxgYDxOgHjDQLGmwSMGQFjlYBxkYCxRsBYJ2BsEDAuETA2CRhbBIxtAsZbBIy3CRjvEDDeJWC8R8B4n4BxmYDxAQHjQwLGFQLGRwSMjwkYnxAwPiVgfEbA+JyA8QUB40sCxlcEjK8JGN8QML4lYHxHwPiegPEDAePHAIwhOD+RcK6ScK4F4ow+W9BDvR0Lt7AwCguPsLAHC2ewMAULP7CwAgsXsDAAifdIbEfieKW3I/EZScVI2EUSLJJMkcSJJEkkISLJD0l0SFJDEhiSrJDEhCShs719rrcjiQRJGkiCQJIBJvExSY5JaEzyYhIVk5SYBMQkGyaxMEmEWmGSA5MIGKTHIDgGmTGIi0FSDEJikA+DaBikwiAQBlkwiCGDBHjJxUskXtLwEoSXDATxCJIRhCLIQxCFIAVBAB6yeIjhIYFOGJ0cOhHcpLgB0LjWoj9v0kh+mGNqjkNK7nERXTW17PrU38randRRP4/8tdToHAuiv9EU/WkY/kwW2q7kff26LmJ32BxX874vV/NBJimzqcpsWmWkPmGud70W1l/VxZLlo0jVRWwXw9iuFSx7+rpomdgvRiHb5vaiZG1PeGz/SN9RkjJ5n6dgyeJ8dz1EliiZXF/YmVfl7LY1ZsmEBZu035LyjWxrRibXNFY6/bXX0Pd3Pft37bVe/R/ba2zJ4nx3Pf62veq2ZbfXJOpv0peKbETJflqyUSX7lfdt1825sP3w9nNX32++n1szDn5tC9to3veBtLthdS5RPtvyjy5vyVIli/NBO0XzPVZ2tC7hSKzyNfO9bI4j6jfy+4rD/ohlf4Dbcc72S+oonzrKo30tmM+Ir9F+vkn5aPe9in3ZfM/2tS21Xf2iP/3Nmqvv88i/IfrHg+iv7+ifCMNfF/2lMP7f0T8Zhr8r+sth9C+J/koY/Q3RPxVE/+JOXKD/XMeOC2bUeY9x7J7jArFftFhDxQUzFo/tHx0XQDbrYK04ZHYfMOuwM+uw49I16VHXlEddxQNax5JHXRWPulKPunxexwmPunz6q+xR15hHXT7bvU9/yXUMOz6VZa44LQqgvxhG/07fL320fhfTdRL7iVX+q+XniSB+7o87SX+mfeGKpXza3uvzWuyXHDzCXXTI9vOHZxuNVrfdarR7IX11abGdFSz9wmqf0+9Eun/R5V3Pflfc59HXmWvMoaz8ii1WsklLliiZMOoxB1dc7JN/L/7X9isOmd0/7/VaTkeDbU3fj+NR/36Oc/91b7a2/8hli9HoT6LBMcXIsp9Y5b+b73Zft997pNvsVLu1TrfT6Kyv1790pi392ofw02+mXHNgmVMAAA==","debug_symbols":"tZbLCoMwEEX/ZdZZOFOtrb9SSokaJRCiRC0U8d8bpQ9p13cTuGFyZnXCnak25dTerG+6gYrLTK6r9Gg7H9O8KCqDdc62t/01JevBSbI9GHrt1zyMOoxUHESR8TUVaRKfN9YZKo6yqL/B/D2Y55/BTJarimSGkQVGPsDIKYycwchHGDmHkU8w8hlFZpiDDHOQYQ4yzEGGOcgwBxnmIMMcZJiDDHNQYA4KzEHBOLjEdNfB6tKZV4FoJl/t+sT46M1PtehDV5l6CmYtGd9+sbqcssp4+0FjYEkVyzkuiYue","brillig_names":["process_log"]},{"name":"public_dispatch","is_unconstrained":true,"custom_attributes":["public"],"abi":{"parameters":[{"name":"selector","type":{"kind":"field"},"visibility":"private"}],"return_type":null,"error_types":{"206160798890201757":{"error_kind":"string","string":"Storage slot 0 not allowed. Storage slots must start from 1."},"2233873454491509486":{"error_kind":"string","string":"Initializer address is not the contract deployer"},"5019202896831570965":{"error_kind":"string","string":"attempt to add with overflow"},"10176877060487216746":{"error_kind":"string","string":"Function add_to_counter_public can only be called internally"},"13699457482007836410":{"error_kind":"string","string":"Not initialized"},"16541607464495309456":{"error_kind":"fmtstring","length":16,"item_types":[]},"16761564377371454734":{"error_kind":"string","string":"Array index out of bounds"},"17618083556256589634":{"error_kind":"string","string":"Initialization hash does not match"},"17843811134343075018":{"error_kind":"string","string":"Stack too deep"}}},"bytecode":"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","debug_symbols":"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","brillig_names":["public_dispatch"]},{"name":"sync_notes","is_unconstrained":true,"custom_attributes":[],"abi":{"parameters":[],"return_type":null,"error_types":{"17843811134343075018":{"error_kind":"string","string":"Stack too deep"}}},"bytecode":"H4sIAAAAAAAA/9VTvQ6CMBBu+YmCMqiJbia+QREMjCbuvkMDMuqAixuPLjXX9FKbMLQ18Uuaa+Hy/ZSDEgUKNSIWkCQHqAnUAL0Px3WGM7NDnmi6LvlrVhaJIZ9D/x9+6sm/gOT3dP9sBjyXQfHjLFJ3Pq4UzYSvzPKb+cy8mci5+kHOEcdM08aghmehoYci3zvYZ4Y+iQVR/3Q0uM9V1YxJvRD4Y/LtHevHWv8WzqnmX9TIwmdX8bwreMdPvG3Lhq81foEA3dM/z8Ie9lOzgDMuiZqN/nVvro/nrScTECRvfuFT84YGAAA=","debug_symbols":"nZLLCoMwEEX/ZdYuMvHV5lekSNQogZBIjIUi/nujSGuLm2QzcId77uos0IlmHmqpezMBqxZQpuVOGu3TsibQWKmUHOrzG8h2EPf+NHK9xclx64ClNAGhO2AZ8XQvlQBW0PWRANLAfhrYzwL7eVifXu4jIbfyQJAgZh8K03zH8jisiMPKOOwWhaV4jWFZfLF7/outPj65lbxR4pCsn3V7cs69RvGn32hNK7rZik3Ek4P+VlgmlPpZP/0G","brillig_names":["sync_notes"]},{"name":"constructor","is_unconstrained":true,"custom_attributes":["public","initializer"],"abi":{"parameters":[],"return_type":null,"error_types":{"2233873454491509486":{"error_kind":"string","string":"Initializer address is not the contract deployer"},"5019202896831570965":{"error_kind":"string","string":"attempt to add with overflow"},"16761564377371454734":{"error_kind":"string","string":"Array index out of bounds"},"17618083556256589634":{"error_kind":"string","string":"Initialization hash does not match"},"17843811134343075018":{"error_kind":"string","string":"Stack too deep"}}},"bytecode":"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","debug_symbols":"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","brillig_names":["constructor"]},{"name":"increase_counter_public","is_unconstrained":true,"custom_attributes":["public"],"abi":{"parameters":[{"name":"counter_id","type":{"kind":"field"},"visibility":"private"}],"return_type":null,"error_types":{"13699457482007836410":{"error_kind":"string","string":"Not initialized"},"16761564377371454734":{"error_kind":"string","string":"Array index out of bounds"},"17843811134343075018":{"error_kind":"string","string":"Stack too deep"}}},"bytecode":"H4sIAAAAAAAA/9VazW7TQBBeN7ETJykxLVRISDyDnaRtcgtCvSE48QAhsVFE/2gLohKHPAUXjty5gITEDSQOiAs3JHgZ6mrH+TyepCndbWGlau3d8TfffLOerO06atoc3ZfZuRJs+roPL9Yig1ihSHReI5vfuvd1vwTzJYPB+syvSfxu2On4QnwG+bd9jWlTH8K0gB9WNM69yRSfx5K2ZX2Oa4iuqZ781fWYz+xs5NOi3uGqwJ98pXG+Y3qUQA9nRq9UPn/UlphmvMj0DcUUqOIaKl9CHP9zDK75GFpSDOSncfIX6OPBi52H+8O9UXx3NDqIDw8dFpfEX2rnwXTPgXmLYz54vr09TsbxwdbL8eFRAdsTsOl4ScmxcV5oh02qj2nr6z68WItcFsMd3ae14MMcDo4xDpshX5Nm8Tey3xjPCn4r41+xo0/2m1C1o09C+L4d/CHh1+zgZ/rU7eBne6CGnfy2CH/ZDv+Y8K9Zwe9k+jTt8M/0Cezon/G/bod/j/BX7OCvE/6qHX3Waf9xQ00b/Q6R75swbm6/GvUW2d+g/xrjapZPGDnMH/Hh+tDvOWm3JnANhDl+j64JftYEPxJW1SDWqkGsZYNYFYNYKwaxGgaxPINY1w1imcxj3SCWSe1NrgnXIFbwj8ZYM4hlct2XDGKZrIVNg1i+QSyTdYLu7XnvMaRnwKvYR5D/miquGxv7CFfQtSToKj3DGtSn6zB85OMJ+lAuK8IcYdH+wwUstPcgRrTHY7oex57pPhAwy4xDRRXjwTHSN+XylMWG7/mcGT3h8jF+PyAvsrf87juyfE917a7JMKQ84LtwD/J1DOP0p1R+veG1Lsyj/WvAfKWPm8wGcyi9z7ZxLxL3EsSDa5LXhooVPmF7Xm1ADcj/Rd9Xo6/LqsNSbFIdDlRxzfOaM6+GLop1lTlFrfnzlVRPpbpHzwalSRGL5sow57E5d1LUJK3/HxmfRfPWVMVc0bWWtW7x+oRcMffkP31+ua2Ps28QWzvjo0e78e7w4Hj/KB7d33uiWOOfGvDTwqxSJn2eWFJ5qkRp0U8t0i0utXRbuEiZtZOWaZmVtin4s1GBebR/o/v0/AuLX7pNpNdDnAPaY9x8GeOyqc65Dm8P6TOCDT190EvSE/VG+7e6Rz2lMuJAPGkrT6zE00t5fAUeXE+XcZJyKJV9rhPaY274zwQ+3vGyLJUW6d8cpO0oll5H4KlUfrtlU/fNbhiST8q5q/IlXTH/LrN/r8/xVYSCuPt/yTPZHERJe5AM1gejUWc4WGH4CrSrW/D/OI7idpIk7XjQSTaSM/3TeGUynS8xrU7108d0r1XRns35MFee5P3X9HkZ/CAW8XCZ/Wd9Tq9CPLiGrg8E/x7zn+MtjOG65lglYQwfDT/pYxt5jbu9UdhL4kEURa1RGJ+VV0knrI9pI60xF54Qm8vsv0HM3/Ux35Khv9Tu1xw7Z0Z/iiGMlSf5MSlHuHbJnnzXJkWONFeHOazdaWvoc9QLsYiHy+x/6nPKCa43uj4Q/FeZ/xxvYYyv3bpgXxfs0/z8IDzdY+ymH6VOfTJ8HOPcaO2k6/oP6iJYm5gqAAA=","debug_symbols":"zZvRbuJADEX/Jc95GMce29NfWa0q2tIKCUFF6Uqrqv++CUtStiCqXjGsX6qkeJxDOPYwEfPWPMzvXp9uF6vH9Utz8+OtWa7vZ9vFetWfvb23zd1msVwunm4P/92k4Q91u/iX59lqOH3Zzjbb5oa0pLaZrx76Q0upz/C4WM6bG+3ef7YNMTBGgDEZGKPAGAPGODCmfH9Ml4AxBIwBPOgAD7rvetAeB6eUx+DU5Sm4lBPBIjpm7g/LFGx0ItiZu32ws/hh8ICeL4Du4wWoZ78eul4AXWi66/rFXadsMgYrp/PoRcj3wUWUPqPbRdEp/YM+XMBrX6BUvgADPYKBHsFAj2CgRzAwVzAwVzAwVzAwVzAwVzAwVwjggQAeCOCBAB4I4IEAHgjggQAeCOCBAB5kwIMMeJABDzLgQQY8yIAHGfAgAx5kwIMMeKCABwp4oIAHCniggAcKeKCABwp4oIAHCnhggAcGeGCABwZ4YIAHBnhggAcGeGCABwZ44IAHDnjggAcOeOCABw544IAHDnjggAcOeFAADwrgQQE8KIAHBfCgAB4UwIMCeFAAD8ppDzhPzxvYv1hkuo/5y8ES8+SSnZnG9Wh/+PEcoyt/H3SlFIqGQtF0oWg4FI2EosmhaDQUjYWi8VA0oXoxherFFKoXU6heTKF6MYXqxRSqF3dXtph9opFyTHPlT0plojE+prnoJ0VySLPLr5XzW+X8Xjl/qZufU+X8VDl/Vzk/V84vlfNXrl+uXL9cuX65cv1y5fqVyvUrletXKtevXKB+c5ny2/nZtCjZGKuZj2AkEkyOBKORYCwSzOkGJaIjjKieh7ngT48op0jflfOVv7mbTjQuxzRdKBoORSOhaHIoGg1FY6Fo/L/RlOPVcL7ys8Dza3NNoWgoFE0XioZD0UgomhyKRkPRWCgaD0UTqhdbqF5scXrxe3/6a7ZZzO6W8/3+pcfX1f3Bdqbt7+f5p51Nz5v1/fzhdTMf9jh9bG8a7jEVazvy/l0OPZWcWyo8vOfdiyYtWRlOafdqasm7nqHn+AM=","brillig_names":["increase_counter_public"]},{"name":"increase_counter_private","is_unconstrained":false,"custom_attributes":["private"],"abi":{"parameters":[{"name":"inputs","type":{"kind":"struct","path":"aztec::context::inputs::private_context_inputs::PrivateContextInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::aztec_address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::aztec_address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_static_call","type":{"kind":"boolean"}}]}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::block_header::BlockHeader","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"content_commitment","type":{"kind":"struct","path":"aztec::protocol_types::content_commitment::ContentCommitment","fields":[{"name":"num_txs","type":{"kind":"field"}},{"name":"blobs_hash","type":{"kind":"field"}},{"name":"in_hash","type":{"kind":"field"}},{"name":"out_hash","type":{"kind":"field"}}]}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"slot_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"integer","sign":"unsigned","width":64}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::eth_address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::aztec_address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"gas_fees","type":{"kind":"struct","path":"aztec::protocol_types::abis::gas_fees::GasFees","fields":[{"name":"fee_per_da_gas","type":{"kind":"field"}},{"name":"fee_per_l2_gas","type":{"kind":"field"}}]}}]}},{"name":"total_fees","type":{"kind":"field"}},{"name":"total_mana_used","type":{"kind":"field"}}]}},{"name":"tx_context","type":{"kind":"struct","path":"aztec::protocol_types::transaction::tx_context::TxContext","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"gas_settings","type":{"kind":"struct","path":"aztec::protocol_types::abis::gas_settings::GasSettings","fields":[{"name":"gas_limits","type":{"kind":"struct","path":"aztec::protocol_types::abis::gas::Gas","fields":[{"name":"da_gas","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"l2_gas","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"teardown_gas_limits","type":{"kind":"struct","path":"aztec::protocol_types::abis::gas::Gas","fields":[{"name":"da_gas","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"l2_gas","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"max_fees_per_gas","type":{"kind":"struct","path":"aztec::protocol_types::abis::gas_fees::GasFees","fields":[{"name":"fee_per_da_gas","type":{"kind":"field"}},{"name":"fee_per_l2_gas","type":{"kind":"field"}}]}},{"name":"max_priority_fees_per_gas","type":{"kind":"struct","path":"aztec::protocol_types::abis::gas_fees::GasFees","fields":[{"name":"fee_per_da_gas","type":{"kind":"field"}},{"name":"fee_per_l2_gas","type":{"kind":"field"}}]}}]}}]}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]},"visibility":"private"},{"name":"counter_id","type":{"kind":"field"},"visibility":"private"}],"return_type":{"abi_type":{"kind":"struct","path":"aztec::protocol_types::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::aztec_address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::aztec_address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_static_call","type":{"kind":"boolean"}}]}},{"name":"args_hash","type":{"kind":"field"}},{"name":"returns_hash","type":{"kind":"field"}},{"name":"min_revertible_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"is_fee_payer","type":{"kind":"boolean"}},{"name":"max_block_number","type":{"kind":"struct","path":"aztec::protocol_types::abis::max_block_number::MaxBlockNumber","fields":[{"name":"_opt","type":{"kind":"struct","path":"std::option::Option","fields":[{"name":"_is_some","type":{"kind":"boolean"}},{"name":"_value","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}},{"name":"note_hash_read_requests","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::read_request::ReadRequest","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"nullifier_read_requests","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::read_request::ReadRequest","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"key_validation_requests_and_generators","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::validation_requests::key_validation_request_and_generator::KeyValidationRequestAndGenerator","fields":[{"name":"request","type":{"kind":"struct","path":"aztec::protocol_types::abis::validation_requests::key_validation_request::KeyValidationRequest","fields":[{"name":"pk_m","type":{"kind":"struct","path":"std::embedded_curve_ops::EmbeddedCurvePoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}},{"name":"is_infinite","type":{"kind":"boolean"}}]}},{"name":"sk_app","type":{"kind":"field"}}]}},{"name":"sk_app_generator","type":{"kind":"field"}}]}}},{"name":"note_hashes","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::note_hash::NoteHash","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"nullifiers","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::nullifier::Nullifier","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"note_hash","type":{"kind":"field"}}]}}},{"name":"private_call_requests","type":{"kind":"array","length":5,"type":{"kind":"struct","path":"aztec::protocol_types::abis::private_call_request::PrivateCallRequest","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::aztec_address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::aztec_address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_static_call","type":{"kind":"boolean"}}]}},{"name":"args_hash","type":{"kind":"field"}},{"name":"returns_hash","type":{"kind":"field"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"end_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"public_call_requests","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::counted::Counted","fields":[{"name":"inner","type":{"kind":"struct","path":"aztec::protocol_types::abis::public_call_request::PublicCallRequest","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::aztec_address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::aztec_address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"args_hash","type":{"kind":"field"}}]}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"public_teardown_call_request","type":{"kind":"struct","path":"aztec::protocol_types::abis::public_call_request::PublicCallRequest","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::aztec_address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::aztec_address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"args_hash","type":{"kind":"field"}}]}},{"name":"l2_to_l1_msgs","type":{"kind":"array","length":2,"type":{"kind":"struct","path":"aztec::protocol_types::messaging::l2_to_l1_message::L2ToL1Message","fields":[{"name":"recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::eth_address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"content","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"private_logs","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::private_log::PrivateLogData","fields":[{"name":"log","type":{"kind":"struct","path":"aztec::protocol_types::abis::log::Log","fields":[{"name":"fields","type":{"kind":"array","length":18,"type":{"kind":"field"}}}]}},{"name":"note_hash_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"contract_class_logs_hashes","type":{"kind":"array","length":1,"type":{"kind":"struct","path":"aztec::protocol_types::abis::log_hash::LogHash","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"length","type":{"kind":"field"}}]}}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"end_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::block_header::BlockHeader","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"content_commitment","type":{"kind":"struct","path":"aztec::protocol_types::content_commitment::ContentCommitment","fields":[{"name":"num_txs","type":{"kind":"field"}},{"name":"blobs_hash","type":{"kind":"field"}},{"name":"in_hash","type":{"kind":"field"}},{"name":"out_hash","type":{"kind":"field"}}]}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"slot_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"integer","sign":"unsigned","width":64}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::eth_address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::aztec_address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"gas_fees","type":{"kind":"struct","path":"aztec::protocol_types::abis::gas_fees::GasFees","fields":[{"name":"fee_per_da_gas","type":{"kind":"field"}},{"name":"fee_per_l2_gas","type":{"kind":"field"}}]}}]}},{"name":"total_fees","type":{"kind":"field"}},{"name":"total_mana_used","type":{"kind":"field"}}]}},{"name":"tx_context","type":{"kind":"struct","path":"aztec::protocol_types::transaction::tx_context::TxContext","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"gas_settings","type":{"kind":"struct","path":"aztec::protocol_types::abis::gas_settings::GasSettings","fields":[{"name":"gas_limits","type":{"kind":"struct","path":"aztec::protocol_types::abis::gas::Gas","fields":[{"name":"da_gas","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"l2_gas","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"teardown_gas_limits","type":{"kind":"struct","path":"aztec::protocol_types::abis::gas::Gas","fields":[{"name":"da_gas","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"l2_gas","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"max_fees_per_gas","type":{"kind":"struct","path":"aztec::protocol_types::abis::gas_fees::GasFees","fields":[{"name":"fee_per_da_gas","type":{"kind":"field"}},{"name":"fee_per_l2_gas","type":{"kind":"field"}}]}},{"name":"max_priority_fees_per_gas","type":{"kind":"struct","path":"aztec::protocol_types::abis::gas_fees::GasFees","fields":[{"name":"fee_per_da_gas","type":{"kind":"field"}},{"name":"fee_per_l2_gas","type":{"kind":"field"}}]}}]}}]}}]},"visibility":"databus"},"error_types":{"5019202896831570965":{"error_kind":"string","string":"attempt to add with overflow"},"17843811134343075018":{"error_kind":"string","string":"Stack too deep"}}},"bytecode":"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","debug_symbols":"7ZbfasIwFMbfJde9OP+SJr7KGKNqlUKpUnUwxHdfIiZVF4VZNhC8KTnJ7+R8fCcJ3at5Pd0tP5pusdqoydtetatZtW1WnY/2Cvk4t1lXXQg326rfqgkaB4Wqu7kflgCHQi2atlYTQ4fiB0yW7QkmawbYcgZmje4Es3Z0H0YjFGk/Fk44acgpQTJRCYoeaFPmdmfDcXNBuKDfC4XycuaGM/rlzA1nzMuZG86Uo50RcHSCBckmuIRjAfvXBdzoAsggEWZ2CXYuBwOW0X8/dnyuJ9Mtcqm7fqyv5RM8t3zMyXdEqQTo++odJNiBPoOzF8uU6SRIQpHkqIXGazE6akGw97Wg08PV8s7ASCf5qdXLv6onIIwXhEBQX8jxwbRv2rZZflz8VEH4SP6UGByUwvXJEn4gRx7I0Q/kmN/m+AgDmn96dHpsS+3OEskn+vCz6ptq2tbB0LC662bRXx9uv9ZxJXZg3a9m9XzX16EXQxuCowyFQHjCgxCxheak7ThFXJD1VX3lbw==","brillig_names":["store_in_execution_cache_oracle_wrapper","enqueue_public_function_call_internal"]},{"name":"add_to_counter_public","is_unconstrained":true,"custom_attributes":["public","internal"],"abi":{"parameters":[{"name":"counter_id","type":{"kind":"field"},"visibility":"private"}],"return_type":null,"error_types":{"206160798890201757":{"error_kind":"string","string":"Storage slot 0 not allowed. Storage slots must start from 1."},"5019202896831570965":{"error_kind":"string","string":"attempt to add with overflow"},"10176877060487216746":{"error_kind":"string","string":"Function add_to_counter_public can only be called internally"},"13699457482007836410":{"error_kind":"string","string":"Not initialized"},"16761564377371454734":{"error_kind":"string","string":"Array index out of bounds"},"17843811134343075018":{"error_kind":"string","string":"Stack too deep"}}},"bytecode":"H4sIAAAAAAAA/+1aT4/bRBQfJ3H+Z+2m2z8XuCBuHOwku9m9BVAFh1IQPSAhgeSuHbRSoWhbEMd8ByQufAyEOHBF4sidCx8DiROdal7z259fnKT1rIrESNHYfs/v/3sz8+LArEfg5hbdGwVn4ebk5UZaI61EFbRqCE7mLnruvgHwZo3K9ohvnfRPktmsp+hXo/zTnqPp0z5C0wP9pOPovLta02dd7Bi5e4wheaf79Ddwz3qE58OfHu2dXFfkF15Wz/fIHg2wR7BhNuay/2Q0yGaMs6hJp9hs92uzRj1aAFvUrAPyb5EOrRp1COvXYRKTnMhn+PQXu+vs2y8//PrsUV68necXxePHAekVKvJrYx+a7T1o3maa9755+PB8eV5c3Pnu/PGTEu2OQluuGxt0Y7kQDwf7q+7FOCQdXnezrQUfgE0itsn94qu8uHiVXGdIlVCRqU0wwX3DzVbtj9y1v1RJ8x7JUx/t9ZI6AL1rXELOpBwNTXkIbAS8GwQ7ILkQFgGMy18MsDbBrgEsJNgYYFq5lNGke7ShjYv7QJfxDPHEkjAiWBdgBwTD7WJEsD7AxBbWB4fuep2aTx5dZF8UHxdZHmzQJ6jQgXkZBbdfQVd80zNln9YXh2nCcYFDiwuOwzHJhbDrAOM4PFR0FdgNgHEc3gTYvnEoNtw3DtEv1wg2BNiYYJi/1wmG+Su2sLREd47DTy7OnxSGBq+LB3TfV/BwWMUkWVqr9Xt1Bdj8JEnEoE1HPzRl5yD/kPDvuntOJgmqxQvKuZxn6XKaLbOjLM9nZ9mY6KPdBh74PyjSYrpcLqdFNlseL6+c/0k+fXAyP5sdp5PTeXG8lb92rukCrrwnBQuLcJ1n6V326si/b8oLRp1n74D4iTxsHy6cfUXWWIHhOYAXjabyrFFBixcVH2ewkSlvyq4oNmYvGhttP/JUxgba51WIDR+0IlP2d5v4aLbpVfDB9wWvp7y3cHOy35jwA/aJ8Ea+ng4JR7vGs/Dvm7IvfMTzgOTZFBvaJknejRUYx+BQ4TNU+PyXaEmMXlVujJT3gg2z8OFnzEeTOVJk6JM+bUWfdgUfbe2qWl9eVB9N5qq835eP5zqRaPYakB7DGvUYEc6iZj0wX0bE+8CPDSd+D9rrhlLsh/5Ua5pIDNj4/h6e25+cs+Q8xu8eABzxfwaaP7jriHDYh0hb62ujn7mp+KObxX6e9vEJn3+Ql9Y/rpF3wU0BHFpTj2v7rk09rm2oM/qLh9ZMEVtYG/0DdBlPhhYjvBZ2FD0E1lX00NajkGBY2zsEw3pZ5Ws7Fm5OXm6kWo1DXpvWyQ48axB+V8FHvaUOaD7gMzw39xGX90Fy31Le13Ja8H5ys+X9jjPwSOEhvAeKPL+42fL7212L7zDm61wjRO8x6KXVzmukt+D/CnrfCS7bUt4xprp/wDIgPuot8mg+HxNMqxGRqa4R9idNzZZCW/O/4P/mZvEXNoN91/RD0mEMOmh2jEkHwf/LzTb+fieb4ftc41AmrnHYMGc/oNxDst9NP/abio1ugQ2aiqw3yUaC/4ebMd4lJqS/i/by2Yt+OmZWjvep3kjD/Zn8wBf1MmatN+JzTt5S8NE3YrOY8LU1IFRooc0jwhcbtjfg434P8f90s7XN58Fl+XBdvUGyY50fE6yv8NXWvUOQ+WpqeDrhvQ8O7Y8r3mvt+scV77UwDvbda4kt9t1r1VGHhsTvVclb8YMdnLeYo00Fn/O2Ks/tNfes0Jcc35gzhwTbNWcigmG8iG8wZ6pqRkehq50VQ6ArZ0X8z6en6ODjG8mOH/qJ5/NjOjLlOt4Bm0qCBgTDNXWXj2xuB2uaTXet7fEcSO3LNQjGNkcY2kv2eb7/x/m/5/58VPbctd6p2GfoyTciz0iRR/sPwK4RB6bsM63Hh+cIXq9895VjczlvtNreUGTQvjnlPgPqJfk0MNX5F5AdNtWJDuF3FFto5/2Q6L8GdWVBdaVHPBCGtuS6wjmKMO3/Fc893uexG22xKfc+Bf9Np7x2fsfeXVU+sAyIj3qHZC/suUdkL0896+fnv3iLvSKyl+C/VWEvTX/tvy2WAfGjCnuhLfFd5s22lfeuKha32ZZjUfBnim21PXof9LGjtfKiz5G2R8c1IgS+m/IF8Xfxv5YvMeGjv7Uaz99XIN8RwbA285kAa7zUNqylu+4P6/7OK5nkZ8fFZH6SzO2nXvlVf2dWnJzmyemyyNI0neRJsY2/+Kq9WsMxnu3ouHvp2TG+0AsJ/y6scfcoZ0KFn8X7rAIv2DA/o6E8a60uP+utyvjNVRlfePdXZRkFNgAY5podQ3eP9kJaIkdI+J/CPsCOLrwj78cK/y7xvyS38gxzjmk1lWeCb/1zn/IGda97H/6MJ9HHZyybxI6PvJodZfOzbJ6mp7O0mKVH2/LqXxofKQ2xOgAA","debug_symbols":"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","brillig_names":["add_to_counter_public"]},{"name":"get_counter_value","is_unconstrained":true,"custom_attributes":[],"abi":{"parameters":[{"name":"counter_id","type":{"kind":"field"},"visibility":"private"}],"return_type":{"abi_type":{"kind":"field"},"visibility":"public"},"error_types":{"206160798890201757":{"error_kind":"string","string":"Storage slot 0 not allowed. Storage slots must start from 1."},"5019202896831570965":{"error_kind":"string","string":"attempt to add with overflow"},"16761564377371454734":{"error_kind":"string","string":"Array index out of bounds"},"17843811134343075018":{"error_kind":"string","string":"Stack too deep"}}},"bytecode":"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","debug_symbols":"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","brillig_names":["get_counter_value"]},{"name":"compute_note_hash_and_optionally_a_nullifier","is_unconstrained":true,"custom_attributes":[],"abi":{"parameters":[{"name":"contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::aztec_address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"},{"name":"nonce","type":{"kind":"field"},"visibility":"private"},{"name":"storage_slot","type":{"kind":"field"},"visibility":"private"},{"name":"note_type_id","type":{"kind":"field"},"visibility":"private"},{"name":"compute_nullifier","type":{"kind":"boolean"},"visibility":"private"},{"name":"serialized_note","type":{"kind":"array","length":0,"type":{"kind":"field"}},"visibility":"private"}],"return_type":{"abi_type":{"kind":"array","length":4,"type":{"kind":"field"}},"visibility":"public"},"error_types":{"16541607464495309456":{"error_kind":"fmtstring","length":16,"item_types":[]},"17843811134343075018":{"error_kind":"string","string":"Stack too deep"}}},"bytecode":"H4sIAAAAAAAA/9VZ227aQBBdsI2xiYHCH0TqWyvZhOsbUi/5DpTAF/QD/NCX9qvLih37MExUJGaisFK0Zmd95uyZ2Ys3HXcq/eNfJzzHoe65y0J9tqEubyuVIlZpybNzJzy7d8IzuhOesSLPjsDT1zTfEneac6k7zcemEV/yAY7gJfc/AHD2N9RZqLtgVwxIlQmD1MJfl/OXzJ0XZf5PWcBMbfAXhN+3wS+J97e6xcexkN8o1M91q+UzvONLEZ4xeQmXbF2wfWe2CGw/mA1z+CezYd4TJ9KtB2NRzKu1dVxobCmMrfNG7VyrHbaR1rkzzdGKYp4xPpw/8SmoT93y6TFbDLaM2RKwkf6+foR+PPYp9PsK7TwnI3eZw2SnmKPWFjkVG+Afy1zSncckrs99ow11j0HPR6aPxV6B+ljo7/WZvsGfnn1Ja9eUiOmJGpFmfezPbBnY4vrcTx5+x+AHsYhHwvp/Cb9Hoe7BO/T+WPDfY/7PeAttqBHHioQ26u/n5OfwPHCn/PlN/d3lOqV3mF7OpTVbD3/V4Gc2/A+En9vgLwl/YIPfnGUeTPBnJeEXNvw3hD+0yZ/mLDmy4b8n/LEJ/nxP++4n15ZmfQjPE2jXW7ur6pozEfrPGVerM9GE8eH64P7rbVOB61iw8RhOBT9TwY+ElSliPShijT7oGPuKWANFrKEilmYcU0UsTb1yRaxCEUsz7zX1ojhK5zRftqEubyzSOU0Rv5LOaZrf7qQ15VcsaIjjS1j/X0zngQnPakZ7Ds118oG+CyPf1+7X5L8Q+BDvXLDdchm7X6wPm/ViczySVcvZpolnwbjyNvwmwvUY+0t7v3TuU9S6lL77h6CrLzHYCmZLwEYcpe/+oRH/a/RH/2PBxvf/a2M5cZf74YCNG++4tipjbu//pLt54/Vrce3cJP+5u1yv3+t+EfXhZ+lc4DoWbPx8kgt+csHPPWLxO3rU0Oc16RTXrV0rlqt1+48tWosSd37v75j/hPX/E37j2Ki+Zc0/rHbV4Wl32C12r6/zl92E4fvSBZ3+Ab+1O0oNHwAA","debug_symbols":"tdfRioQgFAbgd/HaC49aZq+yLIOVDYJYWC0s0buvDbO7w8zl8N8EJ06fIf7I2dngu+16CWmcFtZ+7CxOvVvDlEq1H5x1OcQYrpfH10ycD6tu/cvs0lkuq8sra5XkzKeBtVqUr8cQPWtrefCXRvPbaMxfYyWPT86sRsEVCq5RsEHBDQq2IJiEgMkEkyVMVjBZw+QKJtcw2cDkBibDMkiwDBIsgwTLIMEySLAMEiyD9F4Grbo3lm19oQ2ObnC0hdFS4GjC0RJHKxytcXSFo3FplLg0SlwaJSiNR6m+XA6ui/4+M41b6h9GqPV79k/T1Jyn3g9b9udc9T9SnYdYaa717RYvBZX/I2XKImWhHw==","brillig_names":["compute_note_hash_and_optionally_a_nullifier"]}],"outputs":{"structs":{"functions":[{"kind":"struct","path":"SimpleLogging::add_to_counter_public_abi","fields":[{"name":"parameters","type":{"kind":"struct","path":"SimpleLogging::add_to_counter_public_parameters","fields":[{"name":"counter_id","type":{"kind":"field"}}]}}]},{"kind":"struct","path":"SimpleLogging::constructor_abi","fields":[{"name":"parameters","type":{"kind":"struct","path":"SimpleLogging::constructor_parameters","fields":[]}}]},{"kind":"struct","path":"SimpleLogging::increase_counter_private_abi","fields":[{"name":"parameters","type":{"kind":"struct","path":"SimpleLogging::increase_counter_private_parameters","fields":[{"name":"counter_id","type":{"kind":"field"}}]}}]},{"kind":"struct","path":"SimpleLogging::increase_counter_public_abi","fields":[{"name":"parameters","type":{"kind":"struct","path":"SimpleLogging::increase_counter_public_parameters","fields":[{"name":"counter_id","type":{"kind":"field"}}]}}]}]},"globals":{"storage":[{"kind":"struct","fields":[{"name":"contract_name","value":{"kind":"string","value":"SimpleLogging"}},{"name":"fields","value":{"kind":"struct","fields":[{"name":"counters","value":{"kind":"struct","fields":[{"name":"slot","value":{"kind":"integer","sign":false,"value":"0000000000000000000000000000000000000000000000000000000000000001"}}]}}]}}]}]}},"file_map":{"26":{"source":"use crate::default::Default;\nuse crate::hash::Hasher;\n\ncomptime global RATE: u32 = 3;\n\npub struct Poseidon2 {\n cache: [Field; 3],\n state: [Field; 4],\n cache_size: u32,\n squeeze_mode: bool, // 0 => absorb, 1 => squeeze\n}\n\nimpl Poseidon2 {\n #[no_predicates]\n pub fn hash(input: [Field; N], message_size: u32) -> Field {\n Poseidon2::hash_internal(input, message_size, message_size != N)\n }\n\n pub fn new(iv: Field) -> Poseidon2 {\n let mut result =\n Poseidon2 { cache: [0; 3], state: [0; 4], cache_size: 0, squeeze_mode: false };\n result.state[RATE] = iv;\n result\n }\n\n fn perform_duplex(&mut self) {\n // add the cache into sponge state\n for i in 0..RATE {\n // We effectively zero-pad the cache by only adding to the state\n // cache that is less than the specified `cache_size`\n if i < self.cache_size {\n self.state[i] += self.cache[i];\n }\n }\n self.state = crate::hash::poseidon2_permutation(self.state, 4);\n }\n\n fn absorb(&mut self, input: Field) {\n assert(!self.squeeze_mode);\n if self.cache_size == RATE {\n // If we're absorbing, and the cache is full, apply the sponge permutation to compress the cache\n self.perform_duplex();\n self.cache[0] = input;\n self.cache_size = 1;\n } else {\n // If we're absorbing, and the cache is not full, add the input into the cache\n self.cache[self.cache_size] = input;\n self.cache_size += 1;\n }\n }\n\n fn squeeze(&mut self) -> Field {\n assert(!self.squeeze_mode);\n // If we're in absorb mode, apply sponge permutation to compress the cache.\n self.perform_duplex();\n self.squeeze_mode = true;\n\n // Pop one item off the top of the permutation and return it.\n self.state[0]\n }\n\n fn hash_internal(\n input: [Field; N],\n in_len: u32,\n is_variable_length: bool,\n ) -> Field {\n let two_pow_64 = 18446744073709551616;\n let iv: Field = (in_len as Field) * two_pow_64;\n let mut sponge = Poseidon2::new(iv);\n for i in 0..input.len() {\n if i < in_len {\n sponge.absorb(input[i]);\n }\n }\n\n // In the case where the hash preimage is variable-length, we append `1` to the end of the input, to distinguish\n // from fixed-length hashes. (the combination of this additional field element + the hash IV ensures\n // fixed-length and variable-length hashes do not collide)\n if is_variable_length {\n sponge.absorb(1);\n }\n sponge.squeeze()\n }\n}\n\npub struct Poseidon2Hasher {\n _state: [Field],\n}\n\nimpl Hasher for Poseidon2Hasher {\n fn finish(self) -> Field {\n let iv: Field = (self._state.len() as Field) * 18446744073709551616; // iv = (self._state.len() << 64)\n let mut sponge = Poseidon2::new(iv);\n for i in 0..self._state.len() {\n sponge.absorb(self._state[i]);\n }\n sponge.squeeze()\n }\n\n fn write(&mut self, input: Field) {\n self._state = self._state.push_back(input);\n }\n}\n\nimpl Default for Poseidon2Hasher {\n fn default() -> Self {\n Poseidon2Hasher { _state: &[] }\n }\n}\n","path":"std/hash/poseidon2.nr"},"51":{"source":"use crate::cmp::{Eq, Ord, Ordering};\nuse crate::default::Default;\nuse crate::hash::{Hash, Hasher};\n\npub struct Option {\n _is_some: bool,\n _value: T,\n}\n\nimpl Option {\n /// Constructs a None value\n pub fn none() -> Self {\n Self { _is_some: false, _value: crate::mem::zeroed() }\n }\n\n /// Constructs a Some wrapper around the given value\n pub fn some(_value: T) -> Self {\n Self { _is_some: true, _value }\n }\n\n /// True if this Option is None\n pub fn is_none(self) -> bool {\n !self._is_some\n }\n\n /// True if this Option is Some\n pub fn is_some(self) -> bool {\n self._is_some\n }\n\n /// Asserts `self.is_some()` and returns the wrapped value.\n pub fn unwrap(self) -> T {\n assert(self._is_some);\n self._value\n }\n\n /// Returns the inner value without asserting `self.is_some()`\n /// Note that if `self` is `None`, there is no guarantee what value will be returned,\n /// only that it will be of type `T`.\n pub fn unwrap_unchecked(self) -> T {\n self._value\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, returns the given default value.\n pub fn unwrap_or(self, default: T) -> T {\n if self._is_some {\n self._value\n } else {\n default\n }\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, calls the given function to return\n /// a default value.\n pub fn unwrap_or_else(self, default: fn[Env]() -> T) -> T {\n if self._is_some {\n self._value\n } else {\n default()\n }\n }\n\n /// Asserts `self.is_some()` with a provided custom message and returns the contained `Some` value\n pub fn expect(self, message: fmtstr) -> T {\n assert(self.is_some(), message);\n self._value\n }\n\n /// If self is `Some(x)`, this returns `Some(f(x))`. Otherwise, this returns `None`.\n pub fn map(self, f: fn[Env](T) -> U) -> Option {\n if self._is_some {\n Option::some(f(self._value))\n } else {\n Option::none()\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns the given default value.\n pub fn map_or(self, default: U, f: fn[Env](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns `default()`.\n pub fn map_or_else(self, default: fn[Env1]() -> U, f: fn[Env2](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default()\n }\n }\n\n /// Returns None if self is None. Otherwise, this returns `other`.\n pub fn and(self, other: Self) -> Self {\n if self.is_none() {\n Option::none()\n } else {\n other\n }\n }\n\n /// If self is None, this returns None. Otherwise, this calls the given function\n /// with the Some value contained within self, and returns the result of that call.\n ///\n /// In some languages this function is called `flat_map` or `bind`.\n pub fn and_then(self, f: fn[Env](T) -> Option) -> Option {\n if self._is_some {\n f(self._value)\n } else {\n Option::none()\n }\n }\n\n /// If self is Some, return self. Otherwise, return `other`.\n pub fn or(self, other: Self) -> Self {\n if self._is_some {\n self\n } else {\n other\n }\n }\n\n /// If self is Some, return self. Otherwise, return `default()`.\n pub fn or_else(self, default: fn[Env]() -> Self) -> Self {\n if self._is_some {\n self\n } else {\n default()\n }\n }\n\n // If only one of the two Options is Some, return that option.\n // Otherwise, if both options are Some or both are None, None is returned.\n pub fn xor(self, other: Self) -> Self {\n if self._is_some {\n if other._is_some {\n Option::none()\n } else {\n self\n }\n } else if other._is_some {\n other\n } else {\n Option::none()\n }\n }\n\n /// Returns `Some(x)` if self is `Some(x)` and `predicate(x)` is true.\n /// Otherwise, this returns `None`\n pub fn filter(self, predicate: fn[Env](T) -> bool) -> Self {\n if self._is_some {\n if predicate(self._value) {\n self\n } else {\n Option::none()\n }\n } else {\n Option::none()\n }\n }\n\n /// Flattens an Option> into a Option.\n /// This returns None if the outer Option is None. Otherwise, this returns the inner Option.\n pub fn flatten(option: Option>) -> Option {\n if option._is_some {\n option._value\n } else {\n Option::none()\n }\n }\n}\n\nimpl Default for Option {\n fn default() -> Self {\n Option::none()\n }\n}\n\nimpl Eq for Option\nwhere\n T: Eq,\n{\n fn eq(self, other: Self) -> bool {\n if self._is_some == other._is_some {\n if self._is_some {\n self._value == other._value\n } else {\n true\n }\n } else {\n false\n }\n }\n}\n\nimpl Hash for Option\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self._is_some.hash(state);\n if self._is_some {\n self._value.hash(state);\n }\n }\n}\n\n// For this impl we're declaring Option::none < Option::some\nimpl Ord for Option\nwhere\n T: Ord,\n{\n fn cmp(self, other: Self) -> Ordering {\n if self._is_some {\n if other._is_some {\n self._value.cmp(other._value)\n } else {\n Ordering::greater()\n }\n } else if other._is_some {\n Ordering::less()\n } else {\n Ordering::equal()\n }\n }\n}\n","path":"std/option.nr"},"52":{"source":"pub fn panic(message: fmtstr) -> U {\n assert(false, message);\n crate::mem::zeroed()\n}\n","path":"std/panic.nr"},"62":{"source":"use dep::aztec::macros::aztec;\n\n#[aztec]\ncontract SimpleLogging {\n use dep::aztec::prelude::{Map, PublicMutable};\n use dep::aztec::{\n //keys::getters::get_public_keys,\n macros::{storage::storage, functions::{public, initializer, private, internal}},\n };\n #[storage]\n struct Storage {\n counters: Map, Context>,\n }\n\n #[public]\n #[initializer]\n fn constructor() {\n }\n\n #[private]\n fn increase_counter_private(counter_id: Field) {\n //let msg_sender_npk_m_hash = get_public_keys(context.msg_sender()).npk_m.hash();\n //let secret = context.request_nsk_app(msg_sender_npk_m_hash); // get secret key of caller of function\n //let nullifier = std::hash::pedersen_hash([context.msg_sender().to_field(), secret]); // derive nullifier from sender and secret\n //context.push_nullifier(nullifier);\n SimpleLogging::at(context.this_address()).add_to_counter_public(counter_id).enqueue(\n &mut context,\n );\n }\n\n #[public]\n #[internal]\n fn add_to_counter_public(counter_id: Field) {\n let new_counter_value = storage.counters.at(counter_id).read() + 1;\n storage.counters.at(counter_id).write(new_counter_value);\n }\n\n #[public]\n fn increase_counter_public(counter_id: Field) {\n context.emit_unencrypted_log(/*message=*/\"Counter increased public\");\n SimpleLogging::at(context.this_address()).add_to_counter_public(counter_id);\n }\n unconstrained fn get_counter_value(counter_id: Field) -> pub Field {\n storage.counters.at(counter_id).read()\n }\n}\n","path":"/home/filip/c/chicmoz/services/event-cannon/src/contract-projects/SimpleLogging/src/main.nr"},"63":{"source":"use dep::protocol_types::{\n abis::function_selector::FunctionSelector, address::AztecAddress, traits::Deserialize,\n};\n\nuse crate::context::{gas::GasOpts, private_context::PrivateContext, public_context::PublicContext};\n\nuse crate::hash::hash_args;\nuse crate::oracle::execution_cache;\n\npub trait CallInterface {\n fn get_args(self) -> [Field];\n fn get_selector(self) -> FunctionSelector;\n fn get_name(self) -> str;\n fn get_contract_address(self) -> AztecAddress;\n fn get_is_static(self) -> bool;\n}\n\npub struct PrivateCallInterface {\n pub target_contract: AztecAddress,\n pub selector: FunctionSelector,\n pub name: str,\n pub args_hash: Field,\n pub args: [Field],\n pub return_type: T,\n pub is_static: bool,\n}\n\nimpl PrivateCallInterface {\n pub fn call(self, context: &mut PrivateContext) -> T\n where\n T: Deserialize,\n {\n execution_cache::store(self.args);\n let returns_hash = context.call_private_function_with_args_hash(\n self.target_contract,\n self.selector,\n self.args_hash,\n false,\n );\n let returns: T = returns_hash.get_preimage();\n returns\n }\n\n pub fn view(self, context: &mut PrivateContext) -> T\n where\n T: Deserialize,\n {\n execution_cache::store(self.args);\n let returns_hash = context.call_private_function_with_args_hash(\n self.target_contract,\n self.selector,\n self.args_hash,\n true,\n );\n returns_hash.get_preimage()\n }\n}\n\nimpl CallInterface for PrivateVoidCallInterface {\n fn get_args(self) -> [Field] {\n self.args\n }\n\n fn get_selector(self) -> FunctionSelector {\n self.selector\n }\n\n fn get_name(self) -> str {\n self.name\n }\n\n fn get_contract_address(self) -> AztecAddress {\n self.target_contract\n }\n\n fn get_is_static(self) -> bool {\n self.is_static\n }\n}\n\npub struct PrivateVoidCallInterface {\n pub target_contract: AztecAddress,\n pub selector: FunctionSelector,\n pub name: str,\n pub args_hash: Field,\n pub args: [Field],\n pub return_type: (),\n pub is_static: bool,\n}\n\nimpl PrivateVoidCallInterface {\n pub fn call(self, context: &mut PrivateContext) {\n execution_cache::store(self.args);\n context\n .call_private_function_with_args_hash(\n self.target_contract,\n self.selector,\n self.args_hash,\n false,\n )\n .assert_empty();\n }\n\n pub fn view(self, context: &mut PrivateContext) {\n execution_cache::store(self.args);\n context\n .call_private_function_with_args_hash(\n self.target_contract,\n self.selector,\n self.args_hash,\n true,\n )\n .assert_empty();\n }\n}\n\nimpl CallInterface for PrivateStaticCallInterface {\n fn get_args(self) -> [Field] {\n self.args\n }\n\n fn get_selector(self) -> FunctionSelector {\n self.selector\n }\n\n fn get_name(self) -> str {\n self.name\n }\n\n fn get_contract_address(self) -> AztecAddress {\n self.target_contract\n }\n\n fn get_is_static(self) -> bool {\n self.is_static\n }\n}\n\npub struct PrivateStaticCallInterface {\n pub target_contract: AztecAddress,\n pub selector: FunctionSelector,\n pub name: str,\n pub args_hash: Field,\n pub args: [Field],\n pub return_type: T,\n pub is_static: bool,\n}\n\nimpl PrivateStaticCallInterface {\n pub fn view(self, context: &mut PrivateContext) -> T\n where\n T: Deserialize,\n {\n execution_cache::store(self.args);\n let returns = context.call_private_function_with_args_hash(\n self.target_contract,\n self.selector,\n self.args_hash,\n true,\n );\n returns.get_preimage()\n }\n}\n\nimpl CallInterface for PrivateStaticVoidCallInterface {\n fn get_args(self) -> [Field] {\n self.args\n }\n\n fn get_selector(self) -> FunctionSelector {\n self.selector\n }\n\n fn get_name(self) -> str {\n self.name\n }\n\n fn get_contract_address(self) -> AztecAddress {\n self.target_contract\n }\n\n fn get_is_static(self) -> bool {\n self.is_static\n }\n}\n\npub struct PrivateStaticVoidCallInterface {\n pub target_contract: AztecAddress,\n pub selector: FunctionSelector,\n pub name: str,\n pub args_hash: Field,\n pub args: [Field],\n pub return_type: (),\n pub is_static: bool,\n}\n\nimpl PrivateStaticVoidCallInterface {\n pub fn view(self, context: &mut PrivateContext) {\n execution_cache::store(self.args);\n context\n .call_private_function_with_args_hash(\n self.target_contract,\n self.selector,\n self.args_hash,\n true,\n )\n .assert_empty();\n }\n}\n\nimpl CallInterface for PublicCallInterface {\n fn get_args(self) -> [Field] {\n self.args\n }\n\n fn get_selector(self) -> FunctionSelector {\n self.selector\n }\n\n fn get_name(self) -> str {\n self.name\n }\n\n fn get_contract_address(self) -> AztecAddress {\n self.target_contract\n }\n\n fn get_is_static(self) -> bool {\n self.is_static\n }\n}\n\npub struct PublicCallInterface {\n pub target_contract: AztecAddress,\n pub selector: FunctionSelector,\n pub name: str,\n pub args: [Field],\n pub gas_opts: GasOpts,\n pub return_type: T,\n pub is_static: bool,\n}\n\nimpl PublicCallInterface {\n pub fn with_gas(self: &mut Self, gas_opts: GasOpts) -> &mut Self {\n self.gas_opts = gas_opts;\n self\n }\n\n pub unconstrained fn call(self, context: &mut PublicContext) -> T\n where\n T: Deserialize,\n {\n let returns = context.call_public_function(\n self.target_contract,\n self.selector,\n self.args,\n self.gas_opts,\n );\n Deserialize::deserialize(returns.as_array::())\n }\n\n pub unconstrained fn view(self, context: &mut PublicContext) -> T\n where\n T: Deserialize,\n {\n let returns = context.static_call_public_function(\n self.target_contract,\n self.selector,\n self.args,\n self.gas_opts,\n );\n Deserialize::deserialize(returns.as_array::())\n }\n\n pub fn enqueue(self, context: &mut PrivateContext) {\n let args_hash = hash_args(self.args);\n execution_cache::store(self.args);\n context.call_public_function_with_args_hash(\n self.target_contract,\n self.selector,\n args_hash,\n /*static=*/\n false,\n )\n }\n\n pub fn enqueue_view(self, context: &mut PrivateContext) {\n let args_hash = hash_args(self.args);\n execution_cache::store(self.args);\n context.call_public_function_with_args_hash(\n self.target_contract,\n self.selector,\n args_hash,\n /*static=*/\n true,\n )\n }\n}\n\nimpl CallInterface for PublicVoidCallInterface {\n fn get_args(self) -> [Field] {\n self.args\n }\n\n fn get_selector(self) -> FunctionSelector {\n self.selector\n }\n\n fn get_name(self) -> str {\n self.name\n }\n\n fn get_contract_address(self) -> AztecAddress {\n self.target_contract\n }\n\n fn get_is_static(self) -> bool {\n self.is_static\n }\n}\n\npub struct PublicVoidCallInterface {\n pub target_contract: AztecAddress,\n pub selector: FunctionSelector,\n pub name: str,\n pub args: [Field],\n pub return_type: (),\n pub is_static: bool,\n pub gas_opts: GasOpts,\n}\n\nimpl PublicVoidCallInterface {\n pub fn with_gas(self: &mut Self, gas_opts: GasOpts) -> &mut Self {\n self.gas_opts = gas_opts;\n self\n }\n\n pub unconstrained fn call(self, context: &mut PublicContext) {\n let returns = context.call_public_function(\n self.target_contract,\n self.selector,\n self.args,\n self.gas_opts,\n );\n assert(returns.len() == 0);\n }\n\n pub unconstrained fn view(self, context: &mut PublicContext) {\n let returns = context.static_call_public_function(\n self.target_contract,\n self.selector,\n self.args,\n self.gas_opts,\n );\n assert(returns.len() == 0);\n }\n\n pub fn enqueue(self, context: &mut PrivateContext) {\n let args_hash = hash_args(self.args);\n execution_cache::store(self.args);\n context.call_public_function_with_args_hash(\n self.target_contract,\n self.selector,\n args_hash,\n /*static=*/\n false,\n )\n }\n\n pub fn enqueue_view(self, context: &mut PrivateContext) {\n let args_hash = hash_args(self.args);\n execution_cache::store(self.args);\n context.call_public_function_with_args_hash(\n self.target_contract,\n self.selector,\n args_hash,\n /*static=*/\n true,\n )\n }\n}\n\nimpl CallInterface for PublicStaticCallInterface {\n fn get_args(self) -> [Field] {\n self.args\n }\n\n fn get_selector(self) -> FunctionSelector {\n self.selector\n }\n\n fn get_name(self) -> str {\n self.name\n }\n\n fn get_contract_address(self) -> AztecAddress {\n self.target_contract\n }\n\n fn get_is_static(self) -> bool {\n self.is_static\n }\n}\n\npub struct PublicStaticCallInterface {\n pub target_contract: AztecAddress,\n pub selector: FunctionSelector,\n pub name: str,\n pub args: [Field],\n pub return_type: T,\n pub is_static: bool,\n pub gas_opts: GasOpts,\n}\n\nimpl PublicStaticCallInterface {\n pub fn with_gas(self: &mut Self, gas_opts: GasOpts) -> &mut Self {\n self.gas_opts = gas_opts;\n self\n }\n\n pub unconstrained fn view(self, context: &mut PublicContext) -> T\n where\n T: Deserialize,\n {\n let returns = context.static_call_public_function(\n self.target_contract,\n self.selector,\n self.args,\n self.gas_opts,\n );\n Deserialize::deserialize(returns.as_array::())\n }\n\n pub fn enqueue_view(self, context: &mut PrivateContext) {\n let args_hash = hash_args(self.args);\n execution_cache::store(self.args);\n context.call_public_function_with_args_hash(\n self.target_contract,\n self.selector,\n args_hash,\n /*static=*/\n true,\n )\n }\n}\n\nimpl CallInterface for PublicStaticVoidCallInterface {\n fn get_args(self) -> [Field] {\n self.args\n }\n\n fn get_selector(self) -> FunctionSelector {\n self.selector\n }\n\n fn get_name(self) -> str {\n self.name\n }\n\n fn get_contract_address(self) -> AztecAddress {\n self.target_contract\n }\n\n fn get_is_static(self) -> bool {\n self.is_static\n }\n}\n\npub struct PublicStaticVoidCallInterface {\n target_contract: AztecAddress,\n selector: FunctionSelector,\n name: str,\n args: [Field],\n return_type: (),\n is_static: bool,\n gas_opts: GasOpts,\n}\n\nimpl PublicStaticVoidCallInterface {\n pub fn with_gas(self: &mut Self, gas_opts: GasOpts) -> &mut Self {\n self.gas_opts = gas_opts;\n self\n }\n\n pub unconstrained fn view(self, context: &mut PublicContext) {\n let returns = context.static_call_public_function(\n self.target_contract,\n self.selector,\n self.args,\n self.gas_opts,\n );\n assert(returns.len() == 0);\n }\n\n pub fn enqueue_view(self, context: &mut PrivateContext) {\n let args_hash = hash_args(self.args);\n execution_cache::store(self.args);\n context.call_public_function_with_args_hash(\n self.target_contract,\n self.selector,\n args_hash,\n /*static=*/\n true,\n )\n }\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/context/call_interfaces.nr"},"70":{"source":"use dep::protocol_types::debug_log::debug_log_format;\n\nuse crate::{\n context::{inputs::PrivateContextInputs, returns_hash::ReturnsHash},\n hash::{ArgsHasher, hash_args_array},\n keys::constants::{NULLIFIER_INDEX, NUM_KEY_TYPES, OUTGOING_INDEX, sk_generators},\n messaging::process_l1_to_l2_message,\n oracle::{\n block_header::get_block_header_at,\n call_private_function::call_private_function_internal,\n enqueue_public_function_call::{\n enqueue_public_function_call_internal, notify_set_min_revertible_side_effect_counter,\n set_public_teardown_function_call_internal,\n },\n execution_cache,\n key_validation_request::get_key_validation_request,\n notes::{notify_created_nullifier, notify_nullified_note},\n },\n};\nuse dep::protocol_types::{\n abis::{\n call_context::CallContext,\n function_selector::FunctionSelector,\n log::Log,\n log_hash::LogHash,\n max_block_number::MaxBlockNumber,\n note_hash::NoteHash,\n nullifier::Nullifier,\n private_call_request::PrivateCallRequest,\n private_circuit_public_inputs::PrivateCircuitPublicInputs,\n private_log::PrivateLogData,\n public_call_request::PublicCallRequest,\n read_request::ReadRequest,\n side_effect::Counted,\n validation_requests::{KeyValidationRequest, KeyValidationRequestAndGenerator},\n },\n address::{AztecAddress, EthAddress},\n block_header::BlockHeader,\n constants::{\n MAX_CONTRACT_CLASS_LOGS_PER_CALL, MAX_ENQUEUED_CALLS_PER_CALL,\n MAX_KEY_VALIDATION_REQUESTS_PER_CALL, MAX_L2_TO_L1_MSGS_PER_CALL,\n MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, MAX_NOTE_HASHES_PER_CALL,\n MAX_NULLIFIER_READ_REQUESTS_PER_CALL, MAX_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PRIVATE_LOGS_PER_CALL,\n PRIVATE_LOG_SIZE_IN_FIELDS, PUBLIC_DISPATCH_SELECTOR,\n },\n messaging::l2_to_l1_message::L2ToL1Message,\n traits::Empty,\n};\n\n// When finished, one can call .finish() to convert back to the abi\npub struct PrivateContext {\n // docs:start:private-context\n pub inputs: PrivateContextInputs,\n pub side_effect_counter: u32,\n\n pub min_revertible_side_effect_counter: u32,\n pub is_fee_payer: bool,\n\n pub args_hash: Field,\n pub return_hash: Field,\n\n pub max_block_number: MaxBlockNumber,\n\n pub note_hash_read_requests: BoundedVec,\n pub nullifier_read_requests: BoundedVec,\n key_validation_requests_and_generators: BoundedVec,\n\n pub note_hashes: BoundedVec,\n pub nullifiers: BoundedVec,\n\n pub private_call_requests: BoundedVec,\n pub public_call_requests: BoundedVec, MAX_ENQUEUED_CALLS_PER_CALL>,\n pub public_teardown_call_request: PublicCallRequest,\n pub l2_to_l1_msgs: BoundedVec,\n // docs:end:private-context\n\n // Header of a block whose state is used during private execution (not the block the transaction is included in).\n pub historical_header: BlockHeader,\n\n pub private_logs: BoundedVec,\n pub contract_class_logs_hashes: BoundedVec,\n\n // Contains the last key validation request for each key type. This is used to cache the last request and avoid\n // fetching the same request multiple times.\n // The index of the array corresponds to the key type (0 nullifier, 1 incoming, 2 outgoing, 3 tagging).\n pub last_key_validation_requests: [Option; NUM_KEY_TYPES],\n}\n\nimpl PrivateContext {\n pub fn new(inputs: PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs,\n side_effect_counter: inputs.start_side_effect_counter + 1,\n min_revertible_side_effect_counter: 0,\n is_fee_payer: false,\n args_hash,\n return_hash: 0,\n max_block_number: MaxBlockNumber::empty(),\n note_hash_read_requests: BoundedVec::new(),\n nullifier_read_requests: BoundedVec::new(),\n key_validation_requests_and_generators: BoundedVec::new(),\n note_hashes: BoundedVec::new(),\n nullifiers: BoundedVec::new(),\n historical_header: inputs.historical_header,\n private_call_requests: BoundedVec::new(),\n public_call_requests: BoundedVec::new(),\n public_teardown_call_request: PublicCallRequest::empty(),\n l2_to_l1_msgs: BoundedVec::new(),\n private_logs: BoundedVec::new(),\n contract_class_logs_hashes: BoundedVec::new(),\n last_key_validation_requests: [Option::none(); NUM_KEY_TYPES],\n }\n }\n\n pub fn msg_sender(self) -> AztecAddress {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> AztecAddress {\n self.inputs.call_context.contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.tx_context.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.tx_context.version\n }\n\n pub fn selector(self) -> FunctionSelector {\n self.inputs.call_context.function_selector\n }\n\n pub fn get_args_hash(self) -> Field {\n self.args_hash\n }\n\n pub fn push_note_hash(&mut self, note_hash: Field) {\n self.note_hashes.push(NoteHash { value: note_hash, counter: self.next_counter() });\n\n // WARNING(https://github.com/AztecProtocol/aztec-packages/issues/10558): if you delete this debug_log_format line, some tests fail.\n debug_log_format(\n \"Context.note_hashes, after pushing new note hash: {0}\",\n self.note_hashes.storage().map(|nh: NoteHash| nh.value),\n );\n }\n\n pub fn push_nullifier(&mut self, nullifier: Field) {\n notify_created_nullifier(nullifier);\n self.nullifiers.push(\n Nullifier { value: nullifier, note_hash: 0, counter: self.next_counter() },\n );\n }\n\n pub fn push_nullifier_for_note_hash(&mut self, nullifier: Field, nullified_note_hash: Field) {\n let nullifier_counter = self.next_counter();\n notify_nullified_note(nullifier, nullified_note_hash, nullifier_counter);\n self.nullifiers.push(\n Nullifier {\n value: nullifier,\n note_hash: nullified_note_hash,\n counter: nullifier_counter,\n },\n );\n }\n\n // Returns the header of a block whose state is used during private execution (not the block the transaction is\n // included in).\n pub fn get_block_header(self) -> BlockHeader {\n self.historical_header\n }\n\n // Returns the header of an arbitrary block whose block number is less than or equal to the block number\n // of historical header.\n pub fn get_block_header_at(self, block_number: u32) -> BlockHeader {\n get_block_header_at(block_number, self)\n }\n\n pub fn set_return_hash(&mut self, returns_hasher: ArgsHasher) {\n execution_cache::store(returns_hasher.fields);\n self.return_hash = returns_hasher.hash();\n }\n\n pub fn finish(self) -> PrivateCircuitPublicInputs {\n PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n returns_hash: self.return_hash,\n min_revertible_side_effect_counter: self.min_revertible_side_effect_counter,\n is_fee_payer: self.is_fee_payer,\n max_block_number: self.max_block_number,\n note_hash_read_requests: self.note_hash_read_requests.storage(),\n nullifier_read_requests: self.nullifier_read_requests.storage(),\n key_validation_requests_and_generators: self\n .key_validation_requests_and_generators\n .storage(),\n note_hashes: self.note_hashes.storage(),\n nullifiers: self.nullifiers.storage(),\n private_call_requests: self.private_call_requests.storage(),\n public_call_requests: self.public_call_requests.storage(),\n public_teardown_call_request: self.public_teardown_call_request,\n l2_to_l1_msgs: self.l2_to_l1_msgs.storage(),\n start_side_effect_counter: self.inputs.start_side_effect_counter,\n end_side_effect_counter: self.side_effect_counter,\n private_logs: self.private_logs.storage(),\n contract_class_logs_hashes: self.contract_class_logs_hashes.storage(),\n historical_header: self.historical_header,\n tx_context: self.inputs.tx_context,\n }\n }\n\n pub fn set_as_fee_payer(&mut self) {\n dep::protocol_types::debug_log::debug_log_format(\n \"Setting {0} as fee payer\",\n [self.this_address().to_field()],\n );\n self.is_fee_payer = true;\n }\n\n pub fn end_setup(&mut self) {\n // dep::protocol_types::debug_log::debug_log_format(\n // \"Ending setup at counter {0}\",\n // [self.side_effect_counter as Field]\n // );\n self.min_revertible_side_effect_counter = self.side_effect_counter;\n notify_set_min_revertible_side_effect_counter(self.min_revertible_side_effect_counter);\n }\n\n // docs:start:max-block-number\n pub fn set_tx_max_block_number(&mut self, max_block_number: u32) {\n // docs:end:max-block-number\n self.max_block_number =\n MaxBlockNumber::min_with_u32(self.max_block_number, max_block_number);\n }\n\n pub fn push_note_hash_read_request(&mut self, note_hash: Field) {\n let side_effect = ReadRequest { value: note_hash, counter: self.next_counter() };\n self.note_hash_read_requests.push(side_effect);\n }\n\n pub fn push_nullifier_read_request(&mut self, nullifier: Field) {\n let request = ReadRequest { value: nullifier, counter: self.next_counter() };\n self.nullifier_read_requests.push(request);\n }\n\n pub fn request_nsk_app(&mut self, npk_m_hash: Field) -> Field {\n self.request_sk_app(npk_m_hash, NULLIFIER_INDEX)\n }\n\n pub fn request_ovsk_app(&mut self, ovpk_m_hash: Field) -> Field {\n self.request_sk_app(ovpk_m_hash, OUTGOING_INDEX)\n }\n\n fn request_sk_app(&mut self, pk_m_hash: Field, key_index: Field) -> Field {\n let cached_request =\n self.last_key_validation_requests[key_index].unwrap_or(KeyValidationRequest::empty());\n\n if cached_request.pk_m.hash() == pk_m_hash {\n // We get a match so the cached request is the latest one\n cached_request.sk_app\n } else {\n // We didn't get a match meaning the cached result is stale\n // Typically we'd validate keys by showing that they are the preimage of `pk_m_hash`, but that'd require\n // the oracle returning the master secret keys, which could cause malicious contracts to leak it or learn\n // about secrets from other contracts. We therefore silo secret keys, and rely on the private kernel to\n // validate that we siloed secret key corresponds to correct siloing of the master secret key that hashes\n // to `pk_m_hash`.\n\n /// Safety: Kernels verify that the key validation request is valid and below we verify that a request\n /// for the correct public key has been received.\n let request = unsafe { get_key_validation_request(pk_m_hash, key_index) };\n assert_eq(request.pk_m.hash(), pk_m_hash, \"Obtained invalid key validation request\");\n\n self.key_validation_requests_and_generators.push(\n KeyValidationRequestAndGenerator {\n request,\n sk_app_generator: sk_generators[key_index],\n },\n );\n self.last_key_validation_requests[key_index] = Option::some(request);\n request.sk_app\n }\n }\n\n // docs:start:context_message_portal\n pub fn message_portal(&mut self, recipient: EthAddress, content: Field) {\n // docs:end:context_message_portal\n let message = L2ToL1Message { recipient, content, counter: self.next_counter() };\n self.l2_to_l1_msgs.push(message);\n }\n\n // docs:start:context_consume_l1_to_l2_message\n // docs:start:consume_l1_to_l2_message\n pub fn consume_l1_to_l2_message(\n &mut self,\n content: Field,\n secret: Field,\n sender: EthAddress,\n leaf_index: Field,\n ) {\n // docs:end:context_consume_l1_to_l2_message\n let nullifier = process_l1_to_l2_message(\n self.historical_header.state.l1_to_l2_message_tree.root,\n self.this_address(),\n sender,\n self.chain_id(),\n self.version(),\n content,\n secret,\n leaf_index,\n );\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_nullifier(nullifier)\n }\n // docs:end:consume_l1_to_l2_message\n\n pub fn emit_private_log(&mut self, log: [Field; PRIVATE_LOG_SIZE_IN_FIELDS]) {\n let counter = self.next_counter();\n let private_log = PrivateLogData { log: Log::new(log), note_hash_counter: 0, counter };\n self.private_logs.push(private_log);\n }\n\n pub fn emit_raw_note_log(\n &mut self,\n log: [Field; PRIVATE_LOG_SIZE_IN_FIELDS],\n note_hash_counter: u32,\n ) {\n let counter = self.next_counter();\n let private_log = PrivateLogData { log: Log::new(log), note_hash_counter, counter };\n self.private_logs.push(private_log);\n }\n\n pub fn call_private_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT],\n ) -> ReturnsHash {\n let args_hash = hash_args_array(args);\n execution_cache::store_array(args);\n self.call_private_function_with_args_hash(\n contract_address,\n function_selector,\n args_hash,\n false,\n )\n }\n\n pub fn static_call_private_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT],\n ) -> ReturnsHash {\n let args_hash = hash_args_array(args);\n execution_cache::store_array(args);\n self.call_private_function_with_args_hash(\n contract_address,\n function_selector,\n args_hash,\n true,\n )\n }\n\n pub fn call_private_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n ) -> ReturnsHash {\n self.call_private_function_with_args_hash(contract_address, function_selector, 0, false)\n }\n\n pub fn static_call_private_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n ) -> ReturnsHash {\n self.call_private_function_with_args_hash(contract_address, function_selector, 0, true)\n }\n\n pub fn call_private_function_with_args_hash(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field,\n is_static_call: bool,\n ) -> ReturnsHash {\n let mut is_static_call = is_static_call | self.inputs.call_context.is_static_call;\n let start_side_effect_counter = self.side_effect_counter;\n\n /// Safety: The oracle simulates the private call and returns the value of the side effects counter after\n /// execution of the call (which means that end_side_effect_counter - start_side_effect_counter is\n /// the number of side effects that took place), along with the hash of the return values. We validate these\n /// by requesting a private kernel iteration in which the return values are constrained to hash\n /// to `returns_hash` and the side effects counter to increment from start to end.\n let (end_side_effect_counter, returns_hash) = unsafe {\n call_private_function_internal(\n contract_address,\n function_selector,\n args_hash,\n start_side_effect_counter,\n is_static_call,\n )\n };\n\n self.private_call_requests.push(\n PrivateCallRequest {\n call_context: CallContext {\n msg_sender: self.this_address(),\n contract_address,\n function_selector,\n is_static_call,\n },\n args_hash,\n returns_hash,\n start_side_effect_counter,\n end_side_effect_counter,\n },\n );\n\n // TODO (fees) figure out why this crashes the prover and enable it\n // we need this in order to pay fees inside child call contexts\n // assert(\n // (item.public_inputs.min_revertible_side_effect_counter == 0 as u32)\n // | (item.public_inputs.min_revertible_side_effect_counter\n // > self.min_revertible_side_effect_counter)\n // );\n // if item.public_inputs.min_revertible_side_effect_counter\n // > self.min_revertible_side_effect_counter {\n // self.min_revertible_side_effect_counter = item.public_inputs.min_revertible_side_effect_counter;\n // }\n self.side_effect_counter = end_side_effect_counter + 1;\n ReturnsHash::new(returns_hash)\n }\n\n pub fn call_public_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT],\n ) {\n let args_hash = hash_args_array(args);\n execution_cache::store_array(args);\n self.call_public_function_with_args_hash(\n contract_address,\n function_selector,\n args_hash,\n false,\n )\n }\n\n pub fn static_call_public_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT],\n ) {\n let args_hash = hash_args_array(args);\n execution_cache::store_array(args);\n self.call_public_function_with_args_hash(\n contract_address,\n function_selector,\n args_hash,\n true,\n )\n }\n\n pub fn call_public_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n ) {\n self.call_public_function_with_args_hash(contract_address, function_selector, 0, false)\n }\n\n pub fn static_call_public_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n ) {\n self.call_public_function_with_args_hash(contract_address, function_selector, 0, true)\n }\n\n pub fn call_public_function_with_args_hash(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field,\n is_static_call: bool,\n ) {\n let counter = self.next_counter();\n\n let mut is_static_call = is_static_call | self.inputs.call_context.is_static_call;\n /// Safety: TODO(https://github.com/AztecProtocol/aztec-packages/issues/8985): Fix this.\n /// WARNING: This is insecure and should be temporary!\n /// The oracle hashes the arguments and returns a new args_hash.\n /// new_args = [selector, ...old_args], so as to make it suitable to call the public dispatch function.\n /// We don't validate or compute it in the circuit because a) it's harder to do with slices, and\n /// b) this is only temporary.\n let args_hash = unsafe {\n enqueue_public_function_call_internal(\n contract_address,\n function_selector,\n args_hash,\n counter,\n is_static_call,\n )\n };\n\n // Public calls are rerouted through the dispatch function.\n let function_selector = comptime { FunctionSelector::from_field(PUBLIC_DISPATCH_SELECTOR) };\n\n let call_request = PublicCallRequest {\n msg_sender: self.this_address(),\n contract_address,\n function_selector,\n is_static_call,\n args_hash,\n };\n\n self.public_call_requests.push(Counted::new(call_request, counter));\n }\n\n pub fn set_public_teardown_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT],\n ) {\n let args_hash = hash_args_array(args);\n execution_cache::store_array(args);\n self.set_public_teardown_function_with_args_hash(\n contract_address,\n function_selector,\n args_hash,\n false,\n )\n }\n\n pub fn set_public_teardown_function_with_args_hash(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field,\n is_static_call: bool,\n ) {\n let counter = self.next_counter();\n\n let mut is_static_call = is_static_call | self.inputs.call_context.is_static_call;\n /// Safety: TODO(https://github.com/AztecProtocol/aztec-packages/issues/8985): Fix this.\n /// WARNING: This is insecure and should be temporary!\n /// The oracle hashes the arguments and returns a new args_hash.\n /// new_args = [selector, ...old_args], so as to make it suitable to call the public dispatch function.\n /// We don't validate or compute it in the circuit because a) it's harder to do with slices, and\n /// b) this is only temporary.\n let args_hash = unsafe {\n set_public_teardown_function_call_internal(\n contract_address,\n function_selector,\n args_hash,\n counter,\n is_static_call,\n )\n };\n\n let function_selector = comptime { FunctionSelector::from_field(PUBLIC_DISPATCH_SELECTOR) };\n\n self.public_teardown_call_request = PublicCallRequest {\n msg_sender: self.this_address(),\n contract_address,\n function_selector,\n is_static_call,\n args_hash,\n };\n }\n\n fn next_counter(&mut self) -> u32 {\n let counter = self.side_effect_counter;\n self.side_effect_counter += 1;\n counter\n }\n}\n\nimpl Empty for PrivateContext {\n fn empty() -> Self {\n PrivateContext {\n inputs: PrivateContextInputs::empty(),\n side_effect_counter: 0 as u32,\n min_revertible_side_effect_counter: 0 as u32,\n is_fee_payer: false,\n args_hash: 0,\n return_hash: 0,\n max_block_number: MaxBlockNumber::empty(),\n note_hash_read_requests: BoundedVec::new(),\n nullifier_read_requests: BoundedVec::new(),\n key_validation_requests_and_generators: BoundedVec::new(),\n note_hashes: BoundedVec::new(),\n nullifiers: BoundedVec::new(),\n private_call_requests: BoundedVec::new(),\n public_call_requests: BoundedVec::new(),\n public_teardown_call_request: PublicCallRequest::empty(),\n l2_to_l1_msgs: BoundedVec::new(),\n historical_header: BlockHeader::empty(),\n private_logs: BoundedVec::new(),\n contract_class_logs_hashes: BoundedVec::new(),\n last_key_validation_requests: [Option::none(); NUM_KEY_TYPES],\n }\n }\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/context/private_context.nr"},"71":{"source":"use crate::context::gas::GasOpts;\nuse crate::hash::{\n compute_l1_to_l2_message_hash, compute_l1_to_l2_message_nullifier, compute_secret_hash,\n};\nuse dep::protocol_types::abis::function_selector::FunctionSelector;\nuse dep::protocol_types::address::{AztecAddress, EthAddress};\nuse dep::protocol_types::constants::MAX_FIELD_VALUE;\nuse dep::protocol_types::traits::{Deserialize, Empty, Serialize};\n\npub struct PublicContext {\n pub args_hash: Option,\n pub compute_args_hash: fn() -> Field,\n}\n\nimpl PublicContext {\n pub fn new(compute_args_hash: fn() -> Field) -> Self {\n PublicContext { args_hash: Option::none(), compute_args_hash }\n }\n\n pub fn emit_unencrypted_log(_self: &mut Self, log: T)\n where\n T: Serialize,\n {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { emit_unencrypted_log(Serialize::serialize(log).as_slice()) };\n }\n\n pub fn note_hash_exists(_self: Self, note_hash: Field, leaf_index: Field) -> bool {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { note_hash_exists(note_hash, leaf_index) } == 1\n }\n\n pub fn l1_to_l2_msg_exists(_self: Self, msg_hash: Field, msg_leaf_index: Field) -> bool {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { l1_to_l2_msg_exists(msg_hash, msg_leaf_index) } == 1\n }\n\n pub fn nullifier_exists(_self: Self, unsiloed_nullifier: Field, address: AztecAddress) -> bool {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { nullifier_exists(unsiloed_nullifier, address.to_field()) } == 1\n }\n\n pub fn consume_l1_to_l2_message(\n &mut self,\n content: Field,\n secret: Field,\n sender: EthAddress,\n leaf_index: Field,\n ) {\n let secret_hash = compute_secret_hash(secret);\n let message_hash = compute_l1_to_l2_message_hash(\n sender,\n self.chain_id(),\n /*recipient=*/\n self.this_address(),\n self.version(),\n content,\n secret_hash,\n leaf_index,\n );\n let nullifier = compute_l1_to_l2_message_nullifier(message_hash, secret);\n\n assert(\n !self.nullifier_exists(nullifier, self.this_address()),\n \"L1-to-L2 message is already nullified\",\n );\n assert(\n self.l1_to_l2_msg_exists(message_hash, leaf_index),\n \"Tried to consume nonexistent L1-to-L2 message\",\n );\n\n self.push_nullifier(nullifier);\n }\n\n pub fn message_portal(_self: &mut Self, recipient: EthAddress, content: Field) {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { send_l2_to_l1_msg(recipient, content) };\n }\n\n pub unconstrained fn call_public_function(\n _self: &mut Self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field],\n gas_opts: GasOpts,\n ) -> [Field] {\n let args = args.push_front(function_selector.to_field());\n let success = call(gas_for_call(gas_opts), contract_address, args);\n\n let result_data = returndata_copy(0, returndata_size());\n if !success {\n // Rethrow the revert data.\n avm_revert(result_data);\n }\n result_data\n }\n\n pub unconstrained fn static_call_public_function(\n _self: &mut Self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field],\n gas_opts: GasOpts,\n ) -> [Field] {\n let args = args.push_front(function_selector.to_field());\n let success = call_static(gas_for_call(gas_opts), contract_address, args);\n\n let result_data = returndata_copy(0, returndata_size());\n if !success {\n // Rethrow the revert data.\n avm_revert(result_data);\n }\n result_data\n }\n\n pub fn push_note_hash(_self: &mut Self, note_hash: Field) {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { emit_note_hash(note_hash) };\n }\n pub fn push_nullifier(_self: &mut Self, nullifier: Field) {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { emit_nullifier(nullifier) };\n }\n\n pub fn this_address(_self: Self) -> AztecAddress {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n address()\n }\n }\n pub fn msg_sender(_self: Self) -> AztecAddress {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n sender()\n }\n }\n pub fn selector(_self: Self) -> FunctionSelector {\n // The selector is the first element of the calldata when calling a public function through dispatch.\n /// Safety: AVM opcodes are constrained by the AVM itself\n let raw_selector: [Field; 1] = unsafe { calldata_copy(0, 1) };\n FunctionSelector::from_field(raw_selector[0])\n }\n pub fn get_args_hash(mut self) -> Field {\n if !self.args_hash.is_some() {\n self.args_hash = Option::some((self.compute_args_hash)());\n }\n\n self.args_hash.unwrap_unchecked()\n }\n pub fn transaction_fee(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n transaction_fee()\n }\n }\n\n pub fn chain_id(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n chain_id()\n }\n }\n pub fn version(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n version()\n }\n }\n pub fn block_number(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n block_number()\n }\n }\n pub fn timestamp(_self: Self) -> u64 {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n timestamp()\n }\n }\n pub fn fee_per_l2_gas(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n fee_per_l2_gas()\n }\n }\n pub fn fee_per_da_gas(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n fee_per_da_gas()\n }\n }\n\n pub fn l2_gas_left(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n l2_gas_left()\n }\n }\n pub fn da_gas_left(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n da_gas_left()\n }\n }\n pub fn is_static_call(_self: Self) -> bool {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { is_static_call() } == 1\n }\n\n pub fn raw_storage_read(_self: Self, storage_slot: Field) -> [Field; N] {\n let mut out = [0; N];\n for i in 0..N {\n /// Safety: AVM opcodes are constrained by the AVM itself\n out[i] = unsafe { storage_read(storage_slot + i as Field) };\n }\n out\n }\n\n pub fn storage_read(self, storage_slot: Field) -> T\n where\n T: Deserialize,\n {\n T::deserialize(self.raw_storage_read(storage_slot))\n }\n\n pub fn raw_storage_write(_self: Self, storage_slot: Field, values: [Field; N]) {\n for i in 0..N {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { storage_write(storage_slot + i as Field, values[i]) };\n }\n }\n\n pub fn storage_write(self, storage_slot: Field, value: T)\n where\n T: Serialize,\n {\n self.raw_storage_write(storage_slot, value.serialize());\n }\n}\n\n// Helper functions\nfn gas_for_call(user_gas: GasOpts) -> [Field; 2] {\n // It's ok to use the max possible gas here, because the gas will be\n // capped by the gas left in the (STATIC)CALL instruction.\n [user_gas.l2_gas.unwrap_or(MAX_FIELD_VALUE), user_gas.da_gas.unwrap_or(MAX_FIELD_VALUE)]\n}\n\n// Unconstrained opcode wrappers (do not use directly).\nunconstrained fn address() -> AztecAddress {\n address_opcode()\n}\nunconstrained fn sender() -> AztecAddress {\n sender_opcode()\n}\nunconstrained fn transaction_fee() -> Field {\n transaction_fee_opcode()\n}\nunconstrained fn chain_id() -> Field {\n chain_id_opcode()\n}\nunconstrained fn version() -> Field {\n version_opcode()\n}\nunconstrained fn block_number() -> Field {\n block_number_opcode()\n}\nunconstrained fn timestamp() -> u64 {\n timestamp_opcode()\n}\nunconstrained fn fee_per_l2_gas() -> Field {\n fee_per_l2_gas_opcode()\n}\nunconstrained fn fee_per_da_gas() -> Field {\n fee_per_da_gas_opcode()\n}\nunconstrained fn l2_gas_left() -> Field {\n l2_gas_left_opcode()\n}\nunconstrained fn da_gas_left() -> Field {\n da_gas_left_opcode()\n}\nunconstrained fn is_static_call() -> Field {\n is_static_call_opcode()\n}\nunconstrained fn note_hash_exists(note_hash: Field, leaf_index: Field) -> u1 {\n note_hash_exists_opcode(note_hash, leaf_index)\n}\nunconstrained fn emit_note_hash(note_hash: Field) {\n emit_note_hash_opcode(note_hash)\n}\nunconstrained fn nullifier_exists(nullifier: Field, address: Field) -> u1 {\n nullifier_exists_opcode(nullifier, address)\n}\nunconstrained fn emit_nullifier(nullifier: Field) {\n emit_nullifier_opcode(nullifier)\n}\nunconstrained fn emit_unencrypted_log(message: [Field]) {\n emit_unencrypted_log_opcode(message)\n}\nunconstrained fn l1_to_l2_msg_exists(msg_hash: Field, msg_leaf_index: Field) -> u1 {\n l1_to_l2_msg_exists_opcode(msg_hash, msg_leaf_index)\n}\nunconstrained fn send_l2_to_l1_msg(recipient: EthAddress, content: Field) {\n send_l2_to_l1_msg_opcode(recipient, content)\n}\nunconstrained fn call(gas: [Field; 2], address: AztecAddress, args: [Field]) -> bool {\n call_opcode(gas, address, args)\n}\nunconstrained fn call_static(gas: [Field; 2], address: AztecAddress, args: [Field]) -> bool {\n call_static_opcode(gas, address, args)\n}\n\npub unconstrained fn calldata_copy(cdoffset: u32, copy_size: u32) -> [Field; N] {\n calldata_copy_opcode(cdoffset, copy_size)\n}\n\nunconstrained fn returndata_size() -> u32 {\n returndata_size_opcode()\n}\n\nunconstrained fn returndata_copy(rdoffset: u32, copy_size: u32) -> [Field] {\n returndata_copy_opcode(rdoffset, copy_size)\n}\n\npub unconstrained fn avm_return(returndata: [Field]) {\n return_opcode(returndata)\n}\n\n// This opcode reverts using the exact data given. In general it should only be used\n// to do rethrows, where the revert data is the same as the original revert data.\n// For normal reverts, use Noir's `assert` which, on top of reverting, will also add\n// an error selector to the revert data.\nunconstrained fn avm_revert(revertdata: [Field]) {\n revert_opcode(revertdata)\n}\n\nunconstrained fn storage_read(storage_slot: Field) -> Field {\n storage_read_opcode(storage_slot)\n}\n\nunconstrained fn storage_write(storage_slot: Field, value: Field) {\n storage_write_opcode(storage_slot, value);\n}\n\nimpl Empty for PublicContext {\n fn empty() -> Self {\n PublicContext::new(|| 0)\n }\n}\n\n// AVM oracles (opcodes) follow, do not use directly.\n#[oracle(avmOpcodeAddress)]\nunconstrained fn address_opcode() -> AztecAddress {}\n\n#[oracle(avmOpcodeSender)]\nunconstrained fn sender_opcode() -> AztecAddress {}\n\n#[oracle(avmOpcodeTransactionFee)]\nunconstrained fn transaction_fee_opcode() -> Field {}\n\n#[oracle(avmOpcodeChainId)]\nunconstrained fn chain_id_opcode() -> Field {}\n\n#[oracle(avmOpcodeVersion)]\nunconstrained fn version_opcode() -> Field {}\n\n#[oracle(avmOpcodeBlockNumber)]\nunconstrained fn block_number_opcode() -> Field {}\n\n#[oracle(avmOpcodeTimestamp)]\nunconstrained fn timestamp_opcode() -> u64 {}\n\n#[oracle(avmOpcodeFeePerL2Gas)]\nunconstrained fn fee_per_l2_gas_opcode() -> Field {}\n\n#[oracle(avmOpcodeFeePerDaGas)]\nunconstrained fn fee_per_da_gas_opcode() -> Field {}\n\n#[oracle(avmOpcodeL2GasLeft)]\nunconstrained fn l2_gas_left_opcode() -> Field {}\n\n#[oracle(avmOpcodeDaGasLeft)]\nunconstrained fn da_gas_left_opcode() -> Field {}\n\n#[oracle(avmOpcodeIsStaticCall)]\nunconstrained fn is_static_call_opcode() -> Field {}\n\n#[oracle(avmOpcodeNoteHashExists)]\nunconstrained fn note_hash_exists_opcode(note_hash: Field, leaf_index: Field) -> u1 {}\n\n#[oracle(avmOpcodeEmitNoteHash)]\nunconstrained fn emit_note_hash_opcode(note_hash: Field) {}\n\n#[oracle(avmOpcodeNullifierExists)]\nunconstrained fn nullifier_exists_opcode(nullifier: Field, address: Field) -> u1 {}\n\n#[oracle(avmOpcodeEmitNullifier)]\nunconstrained fn emit_nullifier_opcode(nullifier: Field) {}\n\n#[oracle(avmOpcodeEmitUnencryptedLog)]\nunconstrained fn emit_unencrypted_log_opcode(message: [Field]) {}\n\n#[oracle(avmOpcodeL1ToL2MsgExists)]\nunconstrained fn l1_to_l2_msg_exists_opcode(msg_hash: Field, msg_leaf_index: Field) -> u1 {}\n\n#[oracle(avmOpcodeSendL2ToL1Msg)]\nunconstrained fn send_l2_to_l1_msg_opcode(recipient: EthAddress, content: Field) {}\n\n#[oracle(avmOpcodeCalldataCopy)]\nunconstrained fn calldata_copy_opcode(cdoffset: u32, copy_size: u32) -> [Field; N] {}\n\n#[oracle(avmOpcodeReturndataSize)]\nunconstrained fn returndata_size_opcode() -> u32 {}\n\n#[oracle(avmOpcodeReturndataCopy)]\nunconstrained fn returndata_copy_opcode(rdoffset: u32, copy_size: u32) -> [Field] {}\n\n#[oracle(avmOpcodeReturn)]\nunconstrained fn return_opcode(returndata: [Field]) {}\n\n// This opcode reverts using the exact data given. In general it should only be used\n// to do rethrows, where the revert data is the same as the original revert data.\n// For normal reverts, use Noir's `assert` which, on top of reverting, will also add\n// an error selector to the revert data.\n#[oracle(avmOpcodeRevert)]\nunconstrained fn revert_opcode(revertdata: [Field]) {}\n\n#[oracle(avmOpcodeCall)]\nunconstrained fn call_opcode(\n gas: [Field; 2], // gas allocation: [l2_gas, da_gas]\n address: AztecAddress,\n args: [Field],\n) -> bool {}\n\n#[oracle(avmOpcodeStaticCall)]\nunconstrained fn call_static_opcode(\n gas: [Field; 2], // gas allocation: [l2_gas, da_gas]\n address: AztecAddress,\n args: [Field],\n) -> bool {}\n\n#[oracle(avmOpcodeStorageRead)]\nunconstrained fn storage_read_opcode(storage_slot: Field) -> Field {}\n\n#[oracle(avmOpcodeStorageWrite)]\nunconstrained fn storage_write_opcode(storage_slot: Field, value: Field) {}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/context/public_context.nr"},"73":{"source":"use crate::oracle::{\n execution::{get_block_number, get_chain_id, get_contract_address, get_version},\n storage::storage_read,\n};\nuse dep::protocol_types::{address::AztecAddress, traits::Deserialize};\n\npub struct UnconstrainedContext {\n block_number: u32,\n contract_address: AztecAddress,\n version: Field,\n chain_id: Field,\n}\n\nimpl UnconstrainedContext {\n pub unconstrained fn new() -> Self {\n // We could call these oracles on the getters instead of at creation, which makes sense given that they might\n // not even be accessed. However any performance gains are minimal, and we'd rather fail early if a user\n // incorrectly attempts to create an UnconstrainedContext in an environment in which these oracles are not\n // available.\n let block_number = get_block_number();\n let contract_address = get_contract_address();\n let chain_id = get_chain_id();\n let version = get_version();\n Self { block_number, contract_address, version, chain_id }\n }\n\n pub unconstrained fn at(contract_address: AztecAddress) -> Self {\n let block_number = get_block_number();\n let chain_id = get_chain_id();\n let version = get_version();\n Self { block_number, contract_address, version, chain_id }\n }\n\n pub unconstrained fn at_historical(contract_address: AztecAddress, block_number: u32) -> Self {\n let chain_id = get_chain_id();\n let version = get_version();\n Self { block_number, contract_address, version, chain_id }\n }\n\n pub fn block_number(self) -> u32 {\n self.block_number\n }\n\n pub fn this_address(self) -> AztecAddress {\n self.contract_address\n }\n\n pub fn version(self) -> Field {\n self.version\n }\n\n pub fn chain_id(self) -> Field {\n self.chain_id\n }\n\n pub unconstrained fn raw_storage_read(\n self: Self,\n storage_slot: Field,\n ) -> [Field; N] {\n storage_read(self.this_address(), storage_slot, self.block_number())\n }\n\n pub unconstrained fn storage_read(self, storage_slot: Field) -> T\n where\n T: Deserialize,\n {\n T::deserialize(self.raw_storage_read(storage_slot))\n }\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/context/unconstrained_context.nr"},"83":{"source":"use crate::utils::to_bytes::{arr_to_be_bytes_arr, str_to_be_bytes_arr};\nuse dep::protocol_types::{\n address::{AztecAddress, EthAddress},\n constants::{\n GENERATOR_INDEX__FUNCTION_ARGS, GENERATOR_INDEX__MESSAGE_NULLIFIER,\n GENERATOR_INDEX__SECRET_HASH,\n },\n hash::{poseidon2_hash_with_separator, poseidon2_hash_with_separator_slice, sha256_to_field},\n point::Point,\n traits::Hash,\n};\n\npub use dep::protocol_types::hash::{compute_siloed_nullifier, pedersen_hash};\n\npub fn pedersen_commitment(inputs: [Field; N], hash_index: u32) -> Point {\n std::hash::pedersen_commitment_with_separator(inputs, hash_index)\n}\n\npub fn compute_secret_hash(secret: Field) -> Field {\n poseidon2_hash_with_separator([secret], GENERATOR_INDEX__SECRET_HASH)\n}\n\npub fn compute_unencrypted_log_hash(\n contract_address: AztecAddress,\n log: [u8; N],\n) -> Field {\n let mut hash_bytes = [0; N + 36];\n // Address is converted to 32 bytes in ts\n let address_bytes: [u8; 32] = contract_address.to_field().to_be_bytes();\n for i in 0..32 {\n hash_bytes[i] = address_bytes[i];\n }\n let len_bytes: [u8; 4] = (N as Field).to_be_bytes();\n for i in 0..4 {\n hash_bytes[32 + i] = len_bytes[i];\n }\n for i in 0..N {\n hash_bytes[36 + i] = log[i];\n }\n\n sha256_to_field(hash_bytes)\n}\n\npub fn compute_l1_to_l2_message_hash(\n sender: EthAddress,\n chain_id: Field,\n recipient: AztecAddress,\n version: Field,\n content: Field,\n secret_hash: Field,\n leaf_index: Field,\n) -> Field {\n let mut hash_bytes = [0 as u8; 224];\n let sender_bytes: [u8; 32] = sender.to_field().to_be_bytes();\n let chain_id_bytes: [u8; 32] = chain_id.to_be_bytes();\n let recipient_bytes: [u8; 32] = recipient.to_field().to_be_bytes();\n let version_bytes: [u8; 32] = version.to_be_bytes();\n let content_bytes: [u8; 32] = content.to_be_bytes();\n let secret_hash_bytes: [u8; 32] = secret_hash.to_be_bytes();\n let leaf_index_bytes: [u8; 32] = leaf_index.to_be_bytes();\n\n for i in 0..32 {\n hash_bytes[i] = sender_bytes[i];\n hash_bytes[i + 32] = chain_id_bytes[i];\n hash_bytes[i + 64] = recipient_bytes[i];\n hash_bytes[i + 96] = version_bytes[i];\n hash_bytes[i + 128] = content_bytes[i];\n hash_bytes[i + 160] = secret_hash_bytes[i];\n hash_bytes[i + 192] = leaf_index_bytes[i];\n }\n\n sha256_to_field(hash_bytes)\n}\n\n// The nullifier of a l1 to l2 message is the hash of the message salted with the secret\npub fn compute_l1_to_l2_message_nullifier(message_hash: Field, secret: Field) -> Field {\n poseidon2_hash_with_separator([message_hash, secret], GENERATOR_INDEX__MESSAGE_NULLIFIER)\n}\n\npub struct ArgsHasher {\n pub fields: [Field],\n}\n\nimpl Hash for ArgsHasher {\n fn hash(self) -> Field {\n hash_args(self.fields)\n }\n}\n\nimpl ArgsHasher {\n pub fn new() -> Self {\n Self { fields: [] }\n }\n\n pub fn add(&mut self, field: Field) {\n self.fields = self.fields.push_back(field);\n }\n\n pub fn add_multiple(&mut self, fields: [Field; N]) {\n for i in 0..N {\n self.fields = self.fields.push_back(fields[i]);\n }\n }\n}\n\npub fn hash_args_array(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n poseidon2_hash_with_separator(args, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n\npub fn hash_args(args: [Field]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n poseidon2_hash_with_separator_slice(args, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n\n#[test]\nunconstrained fn compute_var_args_hash() {\n let mut input = ArgsHasher::new();\n for i in 0..100 {\n input.add(i as Field);\n }\n let hash = input.hash();\n dep::std::println(hash);\n assert(hash == 0x19b0d74feb06ebde19edd85a28986c97063e84b3b351a8b666c7cac963ce655f);\n}\n\n#[test]\nunconstrained fn compute_unenc_log_hash_array() {\n let contract_address = AztecAddress::from_field(\n 0x233a3e0df23b2b15b324194cb4a151f26c0b7333250781d34cc269d85dc334c6,\n );\n let log = [\n 0x20660de09f35f876e3e69d227b2a35166ad05f09d82d06366ec9b6f65a51fec2,\n 0x1b52bfe3b8689761916f76dc3d38aa8810860db325cd39ca611eed980091f01c,\n 0x2e559c4045c378a56ad13b9edb1e8de4e7ad3b3aa35cc7ba9ec77f7a68fa43a4,\n 0x25d0f689c4a4178a29d59306f2675824d19be6d25e44fa03b03f49c263053dd2,\n 0x2d513a722d6f352dc0961f156afdc5e31495b9f0e35cb069261a8e55e2df67fd,\n ];\n let serialized_log = arr_to_be_bytes_arr(log);\n let hash = compute_unencrypted_log_hash(contract_address, serialized_log);\n assert(hash == 0x0095b2d17ab72f4b27a341f7ac63e49ec73935ae8c9181a0ac02023eb12f3284);\n}\n\n#[test]\nunconstrained fn compute_unenc_log_hash_addr() {\n let contract_address = AztecAddress::from_field(\n 0x233a3e0df23b2b15b324194cb4a151f26c0b7333250781d34cc269d85dc334c6,\n );\n let log = AztecAddress::from_field(\n 0x26aa302d4715fd8a687453cb26d616b0768027bd54bcae56b09d908ecd9f8303,\n );\n let serialized_log: [u8; 32] = log.to_field().to_be_bytes();\n let hash = compute_unencrypted_log_hash(contract_address, serialized_log);\n assert(hash == 0x0083ab647dfb26e7ddee90a0f4209d049d4660cab42000c544b986aaa84c55a3);\n}\n\n#[test]\nunconstrained fn compute_unenc_log_hash_str() {\n let contract_address = AztecAddress::from_field(\n 0x1b401e1146c5c507962287065c81f0ef7590adae3802c533d7549d6bf0a41bd8,\n );\n let log = \"dummy\";\n let serialized_log = str_to_be_bytes_arr(log);\n let hash = compute_unencrypted_log_hash(contract_address, serialized_log);\n assert(hash == 0x00629e88ebd6374f44aa6cfe07e251ecf07213ebc7267e8f6b578ae57ffd6c20);\n}\n\n#[test]\nunconstrained fn compute_unenc_log_hash_longer_str() {\n let contract_address = AztecAddress::from_field(\n 0x1b401e1146c5c507962287065c81f0ef7590adae3802c533d7549d6bf0a41bd8,\n );\n let log = \"Hello this is a string\";\n let serialized_log = str_to_be_bytes_arr(log);\n let hash = compute_unencrypted_log_hash(contract_address, serialized_log);\n assert(hash == 0x0098637962f7d34fa202b7ffad8a07a238c5d1fd897b82a108f7f467fa73b841);\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/hash.nr"},"99":{"source":"use dep::protocol_types::{\n abis::function_selector::FunctionSelector, address::AztecAddress,\n constants::GENERATOR_INDEX__CONSTRUCTOR, hash::poseidon2_hash_with_separator,\n};\n\nuse crate::{\n context::{PrivateContext, PublicContext},\n oracle::get_contract_instance::{\n get_contract_instance, get_contract_instance_deployer_avm,\n get_contract_instance_initialization_hash_avm,\n },\n};\n\npub fn mark_as_initialized_public(context: &mut PublicContext) {\n let init_nullifier =\n compute_unsiloed_contract_initialization_nullifier((*context).this_address());\n context.push_nullifier(init_nullifier);\n}\n\npub fn mark_as_initialized_private(context: &mut PrivateContext) {\n let init_nullifier =\n compute_unsiloed_contract_initialization_nullifier((*context).this_address());\n context.push_nullifier(init_nullifier);\n}\n\npub fn assert_is_initialized_public(context: &mut PublicContext) {\n let init_nullifier = compute_unsiloed_contract_initialization_nullifier(context.this_address());\n assert(context.nullifier_exists(init_nullifier, context.this_address()), \"Not initialized\");\n}\n\npub fn assert_is_initialized_private(context: &mut PrivateContext) {\n let init_nullifier = compute_unsiloed_contract_initialization_nullifier(context.this_address());\n context.push_nullifier_read_request(init_nullifier);\n}\n\nfn compute_unsiloed_contract_initialization_nullifier(address: AztecAddress) -> Field {\n address.to_field()\n}\n\npub fn assert_initialization_matches_address_preimage_public(context: PublicContext) {\n let address = context.this_address();\n let deployer = get_contract_instance_deployer_avm(address).unwrap();\n let initialization_hash = get_contract_instance_initialization_hash_avm(address).unwrap();\n let expected_init = compute_initialization_hash(context.selector(), context.get_args_hash());\n assert(initialization_hash == expected_init, \"Initialization hash does not match\");\n assert(\n (deployer.is_zero()) | (deployer == context.msg_sender()),\n \"Initializer address is not the contract deployer\",\n );\n}\n\npub fn assert_initialization_matches_address_preimage_private(context: PrivateContext) {\n let address = context.this_address();\n let instance = get_contract_instance(address);\n let expected_init = compute_initialization_hash(context.selector(), context.get_args_hash());\n assert(instance.initialization_hash == expected_init, \"Initialization hash does not match\");\n assert(\n (instance.deployer.is_zero()) | (instance.deployer == context.msg_sender()),\n \"Initializer address is not the contract deployer\",\n );\n}\n\nfn compute_initialization_hash(init_selector: FunctionSelector, init_args_hash: Field) -> Field {\n poseidon2_hash_with_separator(\n [init_selector.to_field(), init_args_hash],\n GENERATOR_INDEX__CONSTRUCTOR,\n )\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/macros/functions/initialization_utils.nr"},"122":{"source":"use dep::protocol_types::{abis::function_selector::FunctionSelector, address::AztecAddress};\n\n#[oracle(enqueuePublicFunctionCall)]\nunconstrained fn enqueue_public_function_call_oracle(\n _contract_address: AztecAddress,\n _function_selector: FunctionSelector,\n _args_hash: Field,\n _side_effect_counter: u32,\n _is_static_call: bool,\n) -> Field {}\n\npub unconstrained fn enqueue_public_function_call_internal(\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field,\n side_effect_counter: u32,\n is_static_call: bool,\n) -> Field {\n enqueue_public_function_call_oracle(\n contract_address,\n function_selector,\n args_hash,\n side_effect_counter,\n is_static_call,\n )\n}\n\n#[oracle(setPublicTeardownFunctionCall)]\nunconstrained fn set_public_teardown_function_call_oracle(\n _contract_address: AztecAddress,\n _function_selector: FunctionSelector,\n _args_hash: Field,\n _side_effect_counter: u32,\n _is_static_call: bool,\n) -> Field {}\n\npub unconstrained fn set_public_teardown_function_call_internal(\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field,\n side_effect_counter: u32,\n is_static_call: bool,\n) -> Field {\n set_public_teardown_function_call_oracle(\n contract_address,\n function_selector,\n args_hash,\n side_effect_counter,\n is_static_call,\n )\n}\n\npub fn notify_set_min_revertible_side_effect_counter(counter: u32) {\n /// Safety: This oracle call returns nothing: we only call it for its side effects. It is therefore always safe\n /// to call.\n unsafe { notify_set_min_revertible_side_effect_counter_oracle_wrapper(counter) };\n}\n\npub unconstrained fn notify_set_min_revertible_side_effect_counter_oracle_wrapper(counter: u32) {\n notify_set_min_revertible_side_effect_counter_oracle(counter);\n}\n\n#[oracle(notifySetMinRevertibleSideEffectCounter)]\nunconstrained fn notify_set_min_revertible_side_effect_counter_oracle(_counter: u32) {}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr"},"123":{"source":"use dep::protocol_types::address::AztecAddress;\n\n#[oracle(getContractAddress)]\nunconstrained fn get_contract_address_oracle() -> AztecAddress {}\n\n#[oracle(getBlockNumber)]\nunconstrained fn get_block_number_oracle() -> u32 {}\n\n#[oracle(getChainId)]\nunconstrained fn get_chain_id_oracle() -> Field {}\n\n#[oracle(getVersion)]\nunconstrained fn get_version_oracle() -> Field {}\n\npub unconstrained fn get_contract_address() -> AztecAddress {\n get_contract_address_oracle()\n}\n\npub unconstrained fn get_block_number() -> u32 {\n get_block_number_oracle()\n}\n\npub unconstrained fn get_chain_id() -> Field {\n get_chain_id_oracle()\n}\n\npub unconstrained fn get_version() -> Field {\n get_version_oracle()\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/oracle/execution.nr"},"124":{"source":"/// Stores values represented as slice in execution cache to be later obtained by its hash.\npub fn store(values: [Field]) {\n /// Safety: This oracle call returns nothing: we only call it for its side effects. It is therefore always safe\n /// to call. When loading the values, however, the caller must check that the values are indeed the preimage.\n unsafe { store_in_execution_cache_oracle_wrapper(values) };\n}\n\n/// Stores values represented as array in execution cache to be later obtained by its hash.\npub fn store_array(values: [Field; N]) {\n /// Safety: This oracle call returns nothing: we only call it for its side effects. It is therefore always safe\n /// to call. When loading the values, however, the caller must check that the values are indeed the preimage.\n unsafe { store_array_in_execution_cache_oracle_wrapper(values) };\n}\n\npub unconstrained fn store_in_execution_cache_oracle_wrapper(values: [Field]) {\n let _ = store_in_execution_cache_oracle(values);\n}\n\npub unconstrained fn store_array_in_execution_cache_oracle_wrapper(values: [Field; N]) {\n let _ = store_array_in_execution_cache_oracle(values);\n}\n\npub unconstrained fn load(hash: Field) -> [Field; N] {\n load_from_execution_cache_oracle(hash)\n}\n\n#[oracle(storeInExecutionCache)]\nunconstrained fn store_in_execution_cache_oracle(_values: [Field]) -> Field {}\n\n#[oracle(storeArrayInExecutionCache)]\nunconstrained fn store_array_in_execution_cache_oracle(_args: [Field; N]) -> Field {}\n\n#[oracle(loadFromExecutionCache)]\nunconstrained fn load_from_execution_cache_oracle(_hash: Field) -> [Field; N] {}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/oracle/execution_cache.nr"},"125":{"source":"use dep::protocol_types::{\n address::AztecAddress, constants::CONTRACT_INSTANCE_LENGTH, contract_class_id::ContractClassId,\n contract_instance::ContractInstance,\n};\n\n// NOTE: this is for use in private only\n#[oracle(getContractInstance)]\nunconstrained fn get_contract_instance_oracle(\n _address: AztecAddress,\n) -> [Field; CONTRACT_INSTANCE_LENGTH] {}\n\n// NOTE: this is for use in private only\nunconstrained fn get_contract_instance_internal(\n address: AztecAddress,\n) -> [Field; CONTRACT_INSTANCE_LENGTH] {\n get_contract_instance_oracle(address)\n}\n\n// NOTE: this is for use in private only\npub fn get_contract_instance(address: AztecAddress) -> ContractInstance {\n /// Safety: The to_address function combines all values in the instance object to produce an address,\n /// so by checking that we get the expected address we validate the entire struct.\n let instance =\n unsafe { ContractInstance::deserialize(get_contract_instance_internal(address)) };\n assert_eq(instance.to_address(), address);\n\n instance\n}\n\n// These oracles each return a ContractInstance member\n// plus a boolean indicating whether the instance was found.\n#[oracle(avmOpcodeGetContractInstanceDeployer)]\nunconstrained fn get_contract_instance_deployer_oracle_avm(\n _address: AztecAddress,\n) -> (Field, bool) {}\n#[oracle(avmOpcodeGetContractInstanceClassId)]\nunconstrained fn get_contract_instance_class_id_oracle_avm(\n _address: AztecAddress,\n) -> (Field, bool) {}\n#[oracle(avmOpcodeGetContractInstanceInitializationHash)]\nunconstrained fn get_contract_instance_initialization_hash_oracle_avm(\n _address: AztecAddress,\n) -> (Field, bool) {}\n\npub unconstrained fn get_contract_instance_deployer_internal_avm(\n address: AztecAddress,\n) -> (Field, bool) {\n get_contract_instance_deployer_oracle_avm(address)\n}\npub unconstrained fn get_contract_instance_class_id_internal_avm(\n address: AztecAddress,\n) -> (Field, bool) {\n get_contract_instance_class_id_oracle_avm(address)\n}\npub unconstrained fn get_contract_instance_initialization_hash_internal_avm(\n address: AztecAddress,\n) -> (Field, bool) {\n get_contract_instance_initialization_hash_oracle_avm(address)\n}\n\npub fn get_contract_instance_deployer_avm(address: AztecAddress) -> Option {\n /// Safety: AVM opcodes are constrained by the AVM itself\n let (member, exists) = unsafe { get_contract_instance_deployer_internal_avm(address) };\n if exists {\n Option::some(AztecAddress::from_field(member))\n } else {\n Option::none()\n }\n}\npub fn get_contract_instance_class_id_avm(address: AztecAddress) -> Option {\n /// Safety: AVM opcodes are constrained by the AVM itself\n let (member, exists) = unsafe { get_contract_instance_class_id_internal_avm(address) };\n if exists {\n Option::some(ContractClassId::from_field(member))\n } else {\n Option::none()\n }\n}\npub fn get_contract_instance_initialization_hash_avm(address: AztecAddress) -> Option {\n /// Safety: AVM opcodes are constrained by the AVM itself\n let (member, exists) =\n unsafe { get_contract_instance_initialization_hash_internal_avm(address) };\n if exists {\n Option::some(member)\n } else {\n Option::none()\n }\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/oracle/get_contract_instance.nr"},"135":{"source":"use crate::{note::{note_header::NoteHeader, note_interface::NoteInterface}, utils::array};\n\nuse dep::protocol_types::{\n address::AztecAddress,\n indexed_tagging_secret::{INDEXED_TAGGING_SECRET_LENGTH, IndexedTaggingSecret},\n};\n\n/// Notifies the simulator that a note has been created, so that it can be returned in future read requests in the same\n/// transaction. This note should only be added to the non-volatile database if found in an actual block.\npub fn notify_created_note(\n storage_slot: Field,\n note_type_id: Field,\n serialized_note: [Field; N],\n note_hash: Field,\n counter: u32,\n) {\n /// Safety: This oracle call returns nothing: we only call it for its side effects. It is therefore always safe\n /// to call.\n unsafe {\n notify_created_note_oracle_wrapper(\n storage_slot,\n note_type_id,\n serialized_note,\n note_hash,\n counter,\n )\n };\n}\n\n/// Notifies the simulator that a note has been nullified, so that it is no longer returned in future read requests in\n/// the same transaction. This note should only be removed to the non-volatile database if its nullifier is found in an\n/// actual block.\npub fn notify_nullified_note(nullifier: Field, note_hash: Field, counter: u32) {\n /// Safety: This oracle call returns nothing: we only call it for its side effects. It is therefore always safe\n /// to call.\n unsafe { notify_nullified_note_oracle_wrapper(nullifier, note_hash, counter) };\n}\n\n/// Notifies the simulator that a non-note nullifier has been created, so that it can be used for note nonces.\npub fn notify_created_nullifier(nullifier: Field) {\n // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe to call.\n unsafe { notify_created_nullifier_oracle_wrapper(nullifier) };\n}\n\nunconstrained fn notify_created_note_oracle_wrapper(\n storage_slot: Field,\n note_type_id: Field,\n serialized_note: [Field; N],\n note_hash: Field,\n counter: u32,\n) {\n let _ = notify_created_note_oracle(\n storage_slot,\n note_type_id,\n serialized_note,\n note_hash,\n counter,\n );\n}\n\n#[oracle(notifyCreatedNote)]\nunconstrained fn notify_created_note_oracle(\n _storage_slot: Field,\n _note_type_id: Field,\n _serialized_note: [Field; N],\n _note_hash: Field,\n _counter: u32,\n) -> Field {}\n\nunconstrained fn notify_nullified_note_oracle_wrapper(\n nullifier: Field,\n note_hash: Field,\n counter: u32,\n) {\n let _ = notify_nullified_note_oracle(nullifier, note_hash, counter);\n}\n\n#[oracle(notifyNullifiedNote)]\nunconstrained fn notify_nullified_note_oracle(\n _nullifier: Field,\n _note_hash: Field,\n _counter: u32,\n) -> Field {}\n\nunconstrained fn notify_created_nullifier_oracle_wrapper(nullifier: Field) {\n let _ = notify_created_nullifier_oracle(nullifier);\n}\n\n#[oracle(notifyCreatedNullifier)]\nunconstrained fn notify_created_nullifier_oracle(_nullifier: Field) -> Field {}\n\n#[oracle(getNotes)]\nunconstrained fn get_notes_oracle(\n _storage_slot: Field,\n _num_selects: u8,\n _select_by_indexes: [u8; N],\n _select_by_offsets: [u8; N],\n _select_by_lengths: [u8; N],\n _select_values: [Field; N],\n _select_comparators: [u8; N],\n _sort_by_indexes: [u8; N],\n _sort_by_offsets: [u8; N],\n _sort_by_lengths: [u8; N],\n _sort_order: [u8; N],\n _limit: u32,\n _offset: u32,\n _status: u8,\n _return_size: u32,\n _placeholder_fields: [Field; S],\n) -> [Field; S] {}\n\nunconstrained fn get_notes_oracle_wrapper(\n storage_slot: Field,\n num_selects: u8,\n select_by_indexes: [u8; N],\n select_by_offsets: [u8; N],\n select_by_lengths: [u8; N],\n select_values: [Field; N],\n select_comparators: [u8; N],\n sort_by_indexes: [u8; N],\n sort_by_offsets: [u8; N],\n sort_by_lengths: [u8; N],\n sort_order: [u8; N],\n limit: u32,\n offset: u32,\n status: u8,\n mut placeholder_fields: [Field; S],\n) -> [Field; S] {\n let return_size = placeholder_fields.len() as u32;\n get_notes_oracle(\n storage_slot,\n num_selects,\n select_by_indexes,\n select_by_offsets,\n select_by_lengths,\n select_values,\n select_comparators,\n sort_by_indexes,\n sort_by_offsets,\n sort_by_lengths,\n sort_order,\n limit,\n offset,\n status,\n return_size,\n placeholder_fields,\n )\n}\n\npub unconstrained fn get_notes(\n storage_slot: Field,\n num_selects: u8,\n select_by_indexes: [u8; M],\n select_by_offsets: [u8; M],\n select_by_lengths: [u8; M],\n select_values: [Field; M],\n select_comparators: [u8; M],\n sort_by_indexes: [u8; M],\n sort_by_offsets: [u8; M],\n sort_by_lengths: [u8; M],\n sort_order: [u8; M],\n limit: u32,\n offset: u32,\n status: u8,\n mut placeholder_opt_notes: [Option; S], // TODO: Remove it and use `limit` to initialize the note array.\n placeholder_fields: [Field; NS], // TODO: Remove it and use `limit` to initialize the note array.\n _placeholder_note_length: [Field; N], // Turbofish hack? Compiler breaks calculating read_offset unless we add this parameter\n) -> [Option; S]\nwhere\n Note: NoteInterface,\n{\n sync_notes_oracle_wrapper();\n let fields = get_notes_oracle_wrapper(\n storage_slot,\n num_selects,\n select_by_indexes,\n select_by_offsets,\n select_by_lengths,\n select_values,\n select_comparators,\n sort_by_indexes,\n sort_by_offsets,\n sort_by_lengths,\n sort_order,\n limit,\n offset,\n status,\n placeholder_fields,\n );\n let num_notes = fields[0] as u32;\n let contract_address = AztecAddress::from_field(fields[1]);\n for i in 0..placeholder_opt_notes.len() {\n if i < num_notes {\n // lengths named as per typescript.\n let return_header_length: u32 = 2; // num_notes & contract_address.\n let extra_preimage_length: u32 = 2; // nonce & note_hash_counter.\n let read_offset: u32 = return_header_length + i * (N + extra_preimage_length);\n\n let nonce = fields[read_offset];\n let note_hash_counter = fields[read_offset + 1] as u32;\n let note_content = array::subarray(fields, read_offset + 2);\n\n let mut note = Note::deserialize_content(note_content);\n note.set_header(NoteHeader { contract_address, nonce, storage_slot, note_hash_counter });\n\n placeholder_opt_notes[i] = Option::some(note);\n };\n }\n placeholder_opt_notes\n}\n\n/// Returns true if the nullifier exists. Note that a `true` value can be constrained by proving existence of the\n/// nullifier, but a `false` value should not be relied upon since other transactions may emit this nullifier before the\n/// current transaction is included in a block. While this might seem of little use at first, certain design patterns\n/// benefit from this abstraction (see e.g. `PrivateMutable`).\npub unconstrained fn check_nullifier_exists(inner_nullifier: Field) -> bool {\n check_nullifier_exists_oracle(inner_nullifier) == 1\n}\n\n#[oracle(checkNullifierExists)]\nunconstrained fn check_nullifier_exists_oracle(_inner_nullifier: Field) -> Field {}\n\n/// Same as `get_indexed_tagging_secret_as_sender`, except it returns the derived tag, ready to be included in a log.\npub unconstrained fn get_app_tag_as_sender(sender: AztecAddress, recipient: AztecAddress) -> Field {\n get_indexed_tagging_secret_as_sender(sender, recipient).compute_tag(recipient)\n}\n\n/// Returns the tagging secret for a given sender and recipient pair, siloed for the current contract address.\n/// Includes the last known index used to send a note tagged with this secret.\n/// For this to work, PXE must know the ivsk_m of the sender.\n/// For the recipient's side, only the address is needed.\npub unconstrained fn get_indexed_tagging_secret_as_sender(\n sender: AztecAddress,\n recipient: AztecAddress,\n) -> IndexedTaggingSecret {\n let result = get_indexed_tagging_secret_as_sender_oracle(sender, recipient);\n IndexedTaggingSecret::deserialize(result)\n}\n\n#[oracle(getIndexedTaggingSecretAsSender)]\nunconstrained fn get_indexed_tagging_secret_as_sender_oracle(\n _sender: AztecAddress,\n _recipient: AztecAddress,\n) -> [Field; INDEXED_TAGGING_SECRET_LENGTH] {}\n\n/// Notifies the simulator that a tag has been used in a note, and to therefore increment the associated index so that\n/// future notes get a different tag and can be discovered by the recipient.\n/// This change should only be persisted in a non-volatile database if the tagged log is found in an actual block -\n/// otherwise e.g. a reverting transaction can cause the sender to accidentally skip indices and later produce notes\n/// that are not found by the recipient.\npub fn increment_app_tagging_secret_index_as_sender(sender: AztecAddress, recipient: AztecAddress) {\n /// Safety: This oracle call returns nothing: we only call it for its side effects. It is therefore always safe\n /// to call.\n unsafe {\n increment_app_tagging_secret_index_as_sender_wrapper(sender, recipient);\n }\n}\n\nunconstrained fn increment_app_tagging_secret_index_as_sender_wrapper(\n sender: AztecAddress,\n recipient: AztecAddress,\n) {\n increment_app_tagging_secret_index_as_sender_oracle(sender, recipient);\n}\n\n#[oracle(incrementAppTaggingSecretIndexAsSender)]\nunconstrained fn increment_app_tagging_secret_index_as_sender_oracle(\n _sender: AztecAddress,\n _recipient: AztecAddress,\n) {}\n\n/// Finds new notes that may have been sent to all registered accounts in PXE in the current contract and makes them available\n/// for later querying via the `get_notes` oracle.\npub fn sync_notes() {\n /// Safety: This oracle call returns nothing: we only call it for its side effects. It is therefore always safe\n /// to call.\n unsafe {\n sync_notes_oracle_wrapper();\n }\n}\n\nunconstrained fn sync_notes_oracle_wrapper() {\n sync_notes_oracle();\n}\n\n#[oracle(syncNotes)]\nunconstrained fn sync_notes_oracle() {}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/oracle/notes.nr"},"138":{"source":"use dep::protocol_types::{address::AztecAddress, traits::Deserialize};\n\n#[oracle(storageRead)]\nunconstrained fn storage_read_oracle(\n address: Field,\n storage_slot: Field,\n block_number: Field,\n length: Field,\n) -> [Field; N] {}\n\npub unconstrained fn raw_storage_read(\n address: AztecAddress,\n storage_slot: Field,\n block_number: u32,\n) -> [Field; N] {\n storage_read_oracle(\n address.to_field(),\n storage_slot,\n block_number as Field,\n N as Field,\n )\n}\n\npub unconstrained fn storage_read(\n address: AztecAddress,\n storage_slot: Field,\n block_number: u32,\n) -> T\nwhere\n T: Deserialize,\n{\n T::deserialize(raw_storage_read(address, storage_slot, block_number))\n}\n\nmod tests {\n use crate::oracle::storage::{raw_storage_read, storage_read};\n use dep::protocol_types::address::AztecAddress;\n\n use crate::test::mocks::mock_struct::MockStruct;\n use std::test::OracleMock;\n\n global address: AztecAddress = AztecAddress::from_field(29);\n global slot: Field = 7;\n global block_number: u32 = 17;\n\n #[test]\n unconstrained fn test_raw_storage_read() {\n let written = MockStruct { a: 13, b: 42 };\n\n let _ = OracleMock::mock(\"storageRead\").returns(written.serialize());\n\n let read: [Field; 2] = raw_storage_read(address, slot, block_number);\n assert_eq(read[0], 13);\n assert_eq(read[1], 42);\n }\n\n #[test]\n unconstrained fn test_storage_read() {\n let written = MockStruct { a: 13, b: 42 };\n\n let _ = OracleMock::mock(\"storageRead\").returns(written.serialize());\n\n let read: MockStruct = storage_read(address, slot, block_number);\n assert_eq(read.a, 13);\n assert_eq(read.b, 42);\n }\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/oracle/storage.nr"},"141":{"source":"use crate::state_vars::storage::Storage;\nuse dep::protocol_types::{\n storage::map::derive_storage_slot_in_map,\n traits::{Deserialize, Serialize, ToField},\n};\n\n// docs:start:map\npub struct Map {\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V,\n}\n// docs:end:map\n\nimpl Storage for Map\nwhere\n T: Serialize + Deserialize,\n{\n fn get_storage_slot(self) -> Field {\n self.storage_slot\n }\n}\n\nimpl Map {\n // docs:start:new\n pub fn new(\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V,\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Map { context, storage_slot, state_var_constructor }\n }\n // docs:end:new\n\n // docs:start:at\n pub fn at(self, key: K) -> V\n where\n K: ToField,\n {\n // TODO(#1204): use a generator index for the storage slot\n let derived_storage_slot = derive_storage_slot_in_map(self.storage_slot, key);\n\n let state_var_constructor = self.state_var_constructor;\n state_var_constructor(self.context, derived_storage_slot)\n }\n // docs:end:at\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/state_vars/map.nr"},"149":{"source":"use crate::context::{PublicContext, UnconstrainedContext};\nuse crate::state_vars::storage::Storage;\nuse dep::protocol_types::traits::{Deserialize, Serialize};\n\n// docs:start:public_mutable_struct\npub struct PublicMutable {\n context: Context,\n storage_slot: Field,\n}\n// docs:end:public_mutable_struct\n\nimpl Storage for PublicMutable\nwhere\n T: Serialize + Deserialize,\n{\n fn get_storage_slot(self) -> Field {\n self.storage_slot\n }\n}\n\nimpl PublicMutable {\n // docs:start:public_mutable_struct_new\n pub fn new(\n // Note: Passing the contexts to new(...) just to have an interface compatible with a Map.\n context: Context,\n storage_slot: Field,\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n PublicMutable { context, storage_slot }\n }\n // docs:end:public_mutable_struct_new\n}\n\nimpl PublicMutable\nwhere\n T: Serialize + Deserialize,\n{\n // docs:start:public_mutable_struct_read\n pub fn read(self) -> T {\n self.context.storage_read(self.storage_slot)\n }\n // docs:end:public_mutable_struct_read\n\n // docs:start:public_mutable_struct_write\n pub fn write(self, value: T) {\n self.context.storage_write(self.storage_slot, value);\n }\n // docs:end:public_mutable_struct_write\n}\n\nimpl PublicMutable\nwhere\n T: Deserialize,\n{\n pub unconstrained fn read(self) -> T {\n self.context.storage_read(self.storage_slot)\n }\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr"},"192":{"source":"use crate::traits::{Deserialize, Empty, FromField, Serialize, ToField};\n\npub struct FunctionSelector {\n // 1st 4-bytes of abi-encoding of function.\n pub inner: u32,\n}\n\nimpl Eq for FunctionSelector {\n fn eq(self, function_selector: FunctionSelector) -> bool {\n function_selector.inner == self.inner\n }\n}\n\nimpl Serialize<1> for FunctionSelector {\n fn serialize(self: Self) -> [Field; 1] {\n [self.inner as Field]\n }\n}\n\nimpl Deserialize<1> for FunctionSelector {\n fn deserialize(fields: [Field; 1]) -> Self {\n Self { inner: fields[0] as u32 }\n }\n}\n\nimpl FromField for FunctionSelector {\n fn from_field(field: Field) -> Self {\n Self { inner: field as u32 }\n }\n}\n\nimpl ToField for FunctionSelector {\n fn to_field(self) -> Field {\n self.inner as Field\n }\n}\n\nimpl Empty for FunctionSelector {\n fn empty() -> Self {\n Self { inner: 0 as u32 }\n }\n}\n\nimpl FunctionSelector {\n pub fn from_u32(value: u32) -> Self {\n Self { inner: value }\n }\n\n pub fn from_signature(signature: str) -> Self {\n let bytes = signature.as_bytes();\n let hash = crate::hash::poseidon2_hash_bytes(bytes);\n\n // `hash` is automatically truncated to fit within 32 bits.\n FunctionSelector::from_field(hash)\n }\n\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n}\n\n#[test]\nfn test_is_valid_selector() {\n let selector = FunctionSelector::from_signature(\"IS_VALID()\");\n assert_eq(selector.to_field(), 0x73cdda47);\n}\n\n#[test]\nfn test_long_selector() {\n let selector =\n FunctionSelector::from_signature(\"foo_and_bar_and_baz_and_foo_bar_baz_and_bar_foo\");\n assert_eq(selector.to_field(), 0x7590a997);\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/noir-protocol-circuits/crates/types/src/abis/function_selector.nr"},"233":{"source":"use crate::{\n abis::function_selector::FunctionSelector,\n address::{\n partial_address::PartialAddress, salted_initialization_hash::SaltedInitializationHash,\n },\n constants::{\n AZTEC_ADDRESS_LENGTH, FUNCTION_TREE_HEIGHT, GENERATOR_INDEX__CONTRACT_ADDRESS_V1,\n MAX_FIELD_VALUE,\n },\n contract_class_id::ContractClassId,\n hash::{poseidon2_hash_with_separator, private_functions_root_from_siblings},\n merkle_tree::membership::MembershipWitness,\n public_keys::{IvpkM, NpkM, OvpkM, PublicKeys, ToPoint, TpkM},\n traits::{Deserialize, Empty, FromField, Serialize, ToField},\n};\n\n// We do below because `use crate::point::Point;` does not work\nuse dep::std::embedded_curve_ops::EmbeddedCurvePoint as Point;\n\nuse crate::public_keys::AddressPoint;\nuse ec::{pow, sqrt};\nuse std::{\n embedded_curve_ops::{EmbeddedCurveScalar, fixed_base_scalar_mul as derive_public_key},\n ops::Add,\n};\n\n// Aztec address\npub struct AztecAddress {\n pub inner: Field,\n}\n\nimpl Eq for AztecAddress {\n fn eq(self, other: Self) -> bool {\n self.to_field() == other.to_field()\n }\n}\n\nimpl Empty for AztecAddress {\n fn empty() -> Self {\n Self { inner: 0 }\n }\n}\n\nimpl ToField for AztecAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl FromField for AztecAddress {\n fn from_field(value: Field) -> AztecAddress {\n AztecAddress { inner: value }\n }\n}\n\nimpl Serialize for AztecAddress {\n fn serialize(self: Self) -> [Field; AZTEC_ADDRESS_LENGTH] {\n [self.to_field()]\n }\n}\n\nimpl Deserialize for AztecAddress {\n fn deserialize(fields: [Field; AZTEC_ADDRESS_LENGTH]) -> Self {\n FromField::from_field(fields[0])\n }\n}\n\nimpl AztecAddress {\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n\n pub fn to_address_point(self) -> AddressPoint {\n // We compute the address point by taking our address, setting it to x, and then solving for y in the\n // equation which defines our bn curve:\n // y^2 = x^3 - 17; x = address\n let x = self.inner;\n let y_squared = pow(x, 3) - 17;\n\n // TODO (#8970): Handle cases where we cannot recover a point from an address\n let mut y = sqrt(y_squared);\n\n // If we get a negative y coordinate (any y where y > MAX_FIELD_VALUE / 2), we pin it to the\n // positive one (any value where y <= MAX_FIELD_VALUE / 2) by subtracting it from the Field modulus\n // note: The field modulus is MAX_FIELD_VALUE + 1\n if (!(y.lt(MAX_FIELD_VALUE / 2) | y.eq(MAX_FIELD_VALUE / 2))) {\n y = (MAX_FIELD_VALUE + 1) - y;\n }\n\n AddressPoint { inner: Point { x: self.inner, y, is_infinite: false } }\n }\n\n pub fn compute(public_keys: PublicKeys, partial_address: PartialAddress) -> AztecAddress {\n let public_keys_hash = public_keys.hash();\n\n let pre_address = poseidon2_hash_with_separator(\n [public_keys_hash.to_field(), partial_address.to_field()],\n GENERATOR_INDEX__CONTRACT_ADDRESS_V1,\n );\n\n let address_point = derive_public_key(EmbeddedCurveScalar::from_field(pre_address)).add(\n public_keys.ivpk_m.to_point(),\n );\n\n // Note that our address is only the x-coordinate of the full address_point. This is okay because when people want to encrypt something and send it to us\n // they can recover our full point using the x-coordinate (our address itself). To do this, they recompute the y-coordinate according to the equation y^2 = x^3 - 17.\n // When they do this, they may get a positive y-coordinate (a value that is less than or equal to MAX_FIELD_VALUE / 2) or\n // a negative y-coordinate (a value that is more than MAX_FIELD_VALUE), and we cannot dictate which one they get and hence the recovered point may sometimes be different than the one\n // our secrect can decrypt. Regardless though, they should and will always encrypt using point with the positive y-coordinate by convention.\n // This ensures that everyone encrypts to the same point given an arbitrary x-coordinate (address). This is allowed because even though our original point may not have a positive y-coordinate,\n // with our original secret, we will be able to derive the secret to the point with the flipped (and now positive) y-coordinate that everyone encrypts to.\n AztecAddress::from_field(address_point.x)\n }\n\n pub fn compute_from_private_function(\n function_selector: FunctionSelector,\n function_vk_hash: Field,\n function_leaf_membership_witness: MembershipWitness,\n contract_class_artifact_hash: Field,\n contract_class_public_bytecode_commitment: Field,\n salted_initialization_hash: SaltedInitializationHash,\n public_keys: PublicKeys,\n ) -> Self {\n let private_functions_root = private_functions_root_from_siblings(\n function_selector,\n function_vk_hash,\n function_leaf_membership_witness.leaf_index,\n function_leaf_membership_witness.sibling_path,\n );\n\n let contract_class_id = ContractClassId::compute(\n contract_class_artifact_hash,\n private_functions_root,\n contract_class_public_bytecode_commitment,\n );\n\n // Compute contract address using the preimage which includes the class_id.\n let partial_address = PartialAddress::compute_from_salted_initialization_hash(\n contract_class_id,\n salted_initialization_hash,\n );\n\n AztecAddress::compute(public_keys, partial_address)\n }\n\n pub fn is_zero(self) -> bool {\n self.inner == 0\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\n#[test]\nfn compute_address_from_partial_and_pub_keys() {\n let public_keys = PublicKeys {\n npk_m: NpkM {\n inner: Point {\n x: 0x22f7fcddfa3ce3e8f0cc8e82d7b94cdd740afa3e77f8e4a63ea78a239432dcab,\n y: 0x0471657de2b6216ade6c506d28fbc22ba8b8ed95c871ad9f3e3984e90d9723a7,\n is_infinite: false,\n },\n },\n ivpk_m: IvpkM {\n inner: Point {\n x: 0x111223493147f6785514b1c195bb37a2589f22a6596d30bb2bb145fdc9ca8f1e,\n y: 0x273bbffd678edce8fe30e0deafc4f66d58357c06fd4a820285294b9746c3be95,\n is_infinite: false,\n },\n },\n ovpk_m: OvpkM {\n inner: Point {\n x: 0x09115c96e962322ffed6522f57194627136b8d03ac7469109707f5e44190c484,\n y: 0x0c49773308a13d740a7f0d4f0e6163b02c5a408b6f965856b6a491002d073d5b,\n is_infinite: false,\n },\n },\n tpk_m: TpkM {\n inner: Point {\n x: 0x00d3d81beb009873eb7116327cf47c612d5758ef083d4fda78e9b63980b2a762,\n y: 0x2f567d22d2b02fe1f4ad42db9d58a36afd1983e7e2909d1cab61cafedad6193a,\n is_infinite: false,\n },\n },\n };\n\n let partial_address = PartialAddress::from_field(\n 0x0a7c585381b10f4666044266a02405bf6e01fa564c8517d4ad5823493abd31de,\n );\n\n let address = AztecAddress::compute(public_keys, partial_address);\n\n // The following value was generated by `derivation.test.ts`.\n // --> Run the test with AZTEC_GENERATE_TEST_DATA=1 flag to update test data.\n let expected_computed_address_from_partial_and_pubkeys =\n 0x24e4646f58b9fbe7d38e317db8d5636c423fbbdfbe119fc190fe9c64747e0c62;\n assert(address.to_field() == expected_computed_address_from_partial_and_pubkeys);\n}\n\n#[test]\nfn compute_preaddress_from_partial_and_pub_keys() {\n let pre_address = poseidon2_hash_with_separator([1, 2], GENERATOR_INDEX__CONTRACT_ADDRESS_V1);\n let expected_computed_preaddress_from_partial_and_pubkey =\n 0x23ce9be3fa3c846b0f9245cc796902e731d04f086e8a42473bb29e405fc98075;\n assert(pre_address == expected_computed_preaddress_from_partial_and_pubkey);\n}\n\n#[test]\nfn from_field_to_field() {\n let address = AztecAddress { inner: 37 };\n assert_eq(FromField::from_field(address.to_field()), address);\n}\n\n#[test]\nfn serde() {\n let address = AztecAddress { inner: 37 };\n assert_eq(Deserialize::deserialize(address.serialize()), address);\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr"},"250":{"source":"use crate::{\n abis::{\n contract_class_function_leaf_preimage::ContractClassFunctionLeafPreimage,\n function_selector::FunctionSelector,\n log_hash::{LogHash, ScopedLogHash},\n note_hash::ScopedNoteHash,\n nullifier::ScopedNullifier,\n private_log::{PrivateLog, PrivateLogData},\n side_effect::{OrderedValue, scoped::Scoped},\n },\n address::{AztecAddress, EthAddress},\n constants::{\n FUNCTION_TREE_HEIGHT, GENERATOR_INDEX__NOTE_HASH_NONCE, GENERATOR_INDEX__OUTER_NULLIFIER,\n GENERATOR_INDEX__SILOED_NOTE_HASH, GENERATOR_INDEX__UNIQUE_NOTE_HASH,\n },\n merkle_tree::root::root_from_sibling_path,\n messaging::l2_to_l1_message::{L2ToL1Message, ScopedL2ToL1Message},\n poseidon2::Poseidon2Sponge,\n traits::{FromField, Hash, is_empty, ToField},\n utils::field::field_from_bytes_32_trunc,\n};\nuse super::{constants::TWO_POW_64, utils::{arrays::array_concat, field::field_from_bytes}};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = std::hash::sha256(bytes_to_hash);\n let hash_in_a_field = field_from_bytes_32_trunc(sha256_hashed);\n\n hash_in_a_field\n}\n\npub fn private_functions_root_from_siblings(\n selector: FunctionSelector,\n vk_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT],\n) -> Field {\n let function_leaf_preimage = ContractClassFunctionLeafPreimage { selector, vk_hash };\n let function_leaf = function_leaf_preimage.hash();\n root_from_sibling_path(\n function_leaf,\n function_leaf_index,\n function_leaf_sibling_path,\n )\n}\n\npub fn compute_note_hash_nonce(first_nullifier_in_tx: Field, note_index_in_tx: u32) -> Field {\n // Hashing the first nullifier with note index in tx is guaranteed to be unique (because all nullifiers are also\n // unique).\n poseidon2_hash_with_separator(\n [first_nullifier_in_tx, note_index_in_tx as Field],\n GENERATOR_INDEX__NOTE_HASH_NONCE,\n )\n}\n\npub fn compute_unique_note_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n let inputs = [nonce, siloed_note_hash];\n poseidon2_hash_with_separator(inputs, GENERATOR_INDEX__UNIQUE_NOTE_HASH)\n}\n\npub fn compute_siloed_note_hash(app: AztecAddress, note_hash: Field) -> Field {\n poseidon2_hash_with_separator(\n [app.to_field(), note_hash],\n GENERATOR_INDEX__SILOED_NOTE_HASH,\n )\n}\n\n/// Computes unique note hashes from siloed note hashes\npub fn compute_unique_siloed_note_hash(\n siloed_note_hash: Field,\n first_nullifier: Field,\n note_index_in_tx: u32,\n) -> Field {\n if siloed_note_hash == 0 {\n 0\n } else {\n let nonce = compute_note_hash_nonce(first_nullifier, note_index_in_tx);\n compute_unique_note_hash(nonce, siloed_note_hash)\n }\n}\n\n/// Siloing in the context of Aztec refers to the process of hashing a note hash with a contract address (this way\n/// the note hash is scoped to a specific contract). This is used to prevent intermingling of notes between contracts.\npub fn silo_note_hash(note_hash: ScopedNoteHash) -> Field {\n if note_hash.contract_address.is_zero() {\n 0\n } else {\n compute_siloed_note_hash(note_hash.contract_address, note_hash.value())\n }\n}\n\npub fn compute_siloed_nullifier(app: AztecAddress, nullifier: Field) -> Field {\n poseidon2_hash_with_separator(\n [app.to_field(), nullifier],\n GENERATOR_INDEX__OUTER_NULLIFIER,\n )\n}\n\npub fn silo_nullifier(nullifier: ScopedNullifier) -> Field {\n if nullifier.contract_address.is_zero() {\n nullifier.value() // Return value instead of 0 because the first nullifier's contract address is zero.\n } else {\n compute_siloed_nullifier(nullifier.contract_address, nullifier.value())\n }\n}\n\npub fn compute_siloed_private_log_field(contract_address: AztecAddress, field: Field) -> Field {\n poseidon2_hash([contract_address.to_field(), field])\n}\n\npub fn silo_private_log(private_log: Scoped) -> PrivateLog {\n if private_log.contract_address.is_zero() {\n private_log.inner.log\n } else {\n let mut fields = private_log.inner.log.fields;\n fields[0] = compute_siloed_private_log_field(private_log.contract_address, fields[0]);\n PrivateLog { fields }\n }\n}\n\nfn compute_siloed_unencrypted_log_hash(address: AztecAddress, log_hash: Field) -> Field {\n accumulate_sha256([address.to_field(), log_hash])\n}\n\npub fn silo_unencrypted_log_hash(log_hash: ScopedLogHash) -> Field {\n if log_hash.contract_address.is_zero() {\n 0\n } else {\n compute_siloed_unencrypted_log_hash(log_hash.contract_address, log_hash.value())\n }\n}\n\npub fn merkle_hash(left: Field, right: Field) -> Field {\n poseidon2_hash([left, right])\n}\n\npub fn compute_l2_to_l1_hash(\n contract_address: AztecAddress,\n recipient: EthAddress,\n content: Field,\n rollup_version_id: Field,\n chain_id: Field,\n) -> Field {\n let mut bytes: [u8; 160] = std::mem::zeroed();\n\n let inputs =\n [contract_address.to_field(), rollup_version_id, recipient.to_field(), chain_id, content];\n for i in 0..5 {\n // TODO are bytes be in fr.to_buffer() ?\n let item_bytes: [u8; 32] = inputs[i].to_be_bytes();\n for j in 0..32 {\n bytes[32 * i + j] = item_bytes[j];\n }\n }\n\n sha256_to_field(bytes)\n}\n\npub fn silo_l2_to_l1_message(\n msg: ScopedL2ToL1Message,\n rollup_version_id: Field,\n chain_id: Field,\n) -> Field {\n if msg.contract_address.is_zero() {\n 0\n } else {\n compute_l2_to_l1_hash(\n msg.contract_address,\n msg.message.recipient,\n msg.message.content,\n rollup_version_id,\n chain_id,\n )\n }\n}\n\n// Computes sha256 hash of 2 input hashes.\n//\n// NB: This method now takes in two 31 byte fields - it assumes that any input\n// is the result of a sha_to_field hash and => is truncated\n//\n// TODO(Jan and David): This is used for the encrypted_log hashes.\n// Can we check to see if we can just use hash_to_field or pedersen_compress here?\n//\npub fn accumulate_sha256(input: [Field; 2]) -> Field {\n // This is a note about the cpp code, since it takes an array of Fields\n // instead of a U128.\n // 4 Field elements when converted to bytes will usually\n // occupy 4 * 32 = 128 bytes.\n // However, this function is making the assumption that each Field\n // only occupies 128 bits.\n //\n // TODO(David): This does not seem to be getting guaranteed anywhere in the code?\n // Concatentate two fields into 32x2 = 64 bytes\n // accumulate_sha256 assumes that the inputs are pre-truncated 31 byte numbers\n let mut hash_input_flattened = [0; 64];\n for offset in 0..input.len() {\n let input_as_bytes: [u8; 32] = input[offset].to_be_bytes();\n for byte_index in 0..32 {\n hash_input_flattened[offset * 32 + byte_index] = input_as_bytes[byte_index];\n }\n }\n\n sha256_to_field(hash_input_flattened)\n}\n\n// Computes the final logs hash for a tx.\npub fn compute_tx_logs_hash(logs: [LogHash; N]) -> Field {\n // Convert each field element into a byte array and append the bytes to `hash_input_flattened`\n let mut hash_input_flattened = [0; N * 32];\n for offset in 0..N {\n // TODO: This is not checking that the decomposition is smaller than P\n let input_as_bytes: [u8; 32] = logs[offset].value.to_be_radix(256);\n for byte_index in 0..32 {\n hash_input_flattened[offset * 32 + byte_index] = input_as_bytes[byte_index];\n }\n }\n // Ideally we would push to a slice then hash, but there is no sha_slice\n // Hardcode to 256 bytes for now\n let mut hash = sha256_to_field(hash_input_flattened);\n // Not having a 0 value hash for empty logs causes issues with empty txs\n // used for padding. Returning early is currently unsupported.\n // We always provide sorted logs here, so 0 being empty means all are empty.\n if is_empty(logs[0]) {\n hash = 0;\n }\n hash\n}\n\npub fn verification_key_hash(key: [Field; N]) -> Field {\n crate::hash::poseidon2_hash(key)\n}\n\n#[inline_always]\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n std::hash::pedersen_hash_with_separator(inputs, hash_index)\n}\n\npub fn poseidon2_hash(inputs: [Field; N]) -> Field {\n std::hash::poseidon2::Poseidon2::hash(inputs, N)\n}\n\n#[no_predicates]\npub fn poseidon2_hash_with_separator(inputs: [Field; N], separator: T) -> Field\nwhere\n T: ToField,\n{\n let inputs_with_separator = array_concat([separator.to_field()], inputs);\n poseidon2_hash(inputs_with_separator)\n}\n\n// Performs a fixed length hash with a subarray of the given input.\n// Useful for SpongeBlob in which we aborb M things and want to check it vs a hash of M elts of an N-len array.\n// Using stdlib poseidon, this will always absorb an extra 1 as a 'variable' hash, and not match spongeblob.squeeze()\n// or any ts implementation. Also checks that any remaining elts not hashed are empty.\n#[no_predicates]\npub fn poseidon2_hash_subarray(input: [Field; N], in_len: u32) -> Field {\n let mut sponge = poseidon2_absorb_chunks(input, in_len, false);\n sponge.squeeze()\n}\n\n// NB the below is the same as std::hash::poseidon2::Poseidon2::hash(), but replacing a range check with a bit check,\n// and absorbing in chunks of 3 below.\n#[no_predicates]\npub fn poseidon2_cheaper_variable_hash(input: [Field; N], in_len: u32) -> Field {\n let mut sponge = poseidon2_absorb_chunks(input, in_len, true);\n // In the case where the hash preimage is variable-length, we append `1` to the end of the input, to distinguish\n // from fixed-length hashes. (the combination of this additional field element + the hash IV ensures\n // fixed-length and variable-length hashes do not collide)\n if in_len != N {\n sponge.absorb(1);\n }\n sponge.squeeze()\n}\n\n// The below fn reduces gates of a conditional poseidon2 hash by approx 3x (thank you ~* Giant Brain Dev @IlyasRidhuan *~ for the idea)\n// Why? Because when we call stdlib poseidon, we call absorb for each item. When absorbing is conditional, it seems the compiler does not know\n// what cache_size will be when calling absorb, so it assigns the permutation gates for /each i/ rather than /every 3rd i/, which is actually required.\n// The below code forces the compiler to:\n// - absorb normally up to 2 times to set cache_size to 1\n// - absorb in chunks of 3 to ensure perm. only happens every 3rd absorb\n// - absorb normally up to 2 times to add any remaining values to the hash\n// In fixed len hashes, the compiler is able to tell that it will only need to perform the permutation every 3 absorbs.\n// NB: it also replaces unnecessary range checks (i < thing) with a bit check (&= i != thing), which alone reduces the gates of a var. hash by half.\n\n#[no_predicates]\nfn poseidon2_absorb_chunks(\n input: [Field; N],\n in_len: u32,\n variable: bool,\n) -> Poseidon2Sponge {\n let iv: Field = (in_len as Field) * TWO_POW_64;\n let mut sponge = Poseidon2Sponge::new(iv);\n // Even though shift is always 1 here, if we input in_len = 0 we get an underflow\n // since we cannot isolate computation branches. The below is just to avoid that.\n let shift = if in_len == 0 { 0 } else { 1 };\n if in_len != 0 {\n // cache_size = 0, init absorb\n sponge.cache[0] = input[0];\n sponge.cache_size = 1;\n // shift = num elts already added to make cache_size 1 = 1 for a fresh sponge\n // M = max_chunks = (N - 1 - (N - 1) % 3) / 3: (must be written as a fn of N to compile)\n // max_remainder = (N - 1) % 3;\n // max_chunks = (N - 1 - max_remainder) / 3;\n sponge = poseidon2_absorb_chunks_loop::(\n sponge,\n input,\n in_len,\n variable,\n shift,\n );\n }\n sponge\n}\n\n// NB: If it's not required to check that the non-absorbed elts of 'input' are 0s, set skip_0_check=true\n#[no_predicates]\npub fn poseidon2_absorb_chunks_existing_sponge(\n in_sponge: Poseidon2Sponge,\n input: [Field; N],\n in_len: u32,\n skip_0_check: bool,\n) -> Poseidon2Sponge {\n let mut sponge = in_sponge;\n // 'shift' is to account for already added inputs\n let mut shift = 0;\n // 'stop' is to avoid an underflow when inputting in_len = 0\n let mut stop = false;\n for i in 0..3 {\n if shift == in_len {\n stop = true;\n }\n if (sponge.cache_size != 1) & (!stop) {\n sponge.absorb(input[i]);\n shift += 1;\n }\n }\n sponge = if stop {\n sponge\n } else {\n // max_chunks = (N - (N % 3)) / 3;\n poseidon2_absorb_chunks_loop::(\n sponge,\n input,\n in_len,\n skip_0_check,\n shift,\n )\n };\n sponge\n}\n\n// The below is the loop to absorb elts into a poseidon sponge in chunks of 3\n// shift - the num of elts already absorbed to ensure the sponge's cache_size = 1\n// M - the max number of chunks required to absorb N things (must be comptime to compile)\n// NB: The 0 checks ('Found non-zero field...') are messy, but having a separate loop over N to check\n// for 0s costs 3N gates. Current approach is approx 2N gates.\n#[no_predicates]\nfn poseidon2_absorb_chunks_loop(\n in_sponge: Poseidon2Sponge,\n input: [Field; N],\n in_len: u32,\n variable: bool,\n shift: u32,\n) -> Poseidon2Sponge {\n assert(in_len <= N, \"Given in_len to absorb is larger than the input array len\");\n // When we have an existing sponge, we may have a shift of 0, and the final 'k+2' below = N\n // The below avoids an overflow\n let skip_last = 3 * M == N;\n // Writing in_sponge: &mut does not compile\n let mut sponge = in_sponge;\n let mut should_add = true;\n // The num of things left over after absorbing in 3s\n let remainder = (in_len - shift) % 3;\n // The num of chunks of 3 to absorb (maximum M)\n let chunks = (in_len - shift - remainder) / 3;\n for i in 0..M {\n // Now we loop through cache size = 1 -> 3\n should_add &= i != chunks;\n // This is the index at the start of the chunk (for readability)\n let k = 3 * i + shift;\n if should_add {\n // cache_size = 1, 2 => just assign\n sponge.cache[1] = input[k];\n sponge.cache[2] = input[k + 1];\n // cache_size = 3 => duplex + perm\n for j in 0..3 {\n sponge.state[j] += sponge.cache[j];\n }\n sponge.state = std::hash::poseidon2_permutation(sponge.state, 4);\n sponge.cache[0] = input[k + 2];\n // cache_size is now 1 again, repeat loop\n } else if (!variable) & (i != chunks) {\n // if we are hashing a fixed len array which is a subarray, we check the remaining elts are 0\n // NB: we don't check at i == chunks, because that chunk contains elts to be absorbed or checked below\n let last_0 = if (i == M - 1) & (skip_last) {\n 0\n } else {\n input[k + 2]\n };\n let all_0 = (input[k] == 0) & (input[k + 1] == 0) & (last_0 == 0);\n assert(all_0, \"Found non-zero field after breakpoint\");\n }\n }\n // we have 'remainder' num of items left to absorb\n should_add = true;\n // below is to avoid overflows (i.e. if inlen is close to N)\n let mut should_check = !variable;\n for i in 0..3 {\n should_add &= i != remainder;\n should_check &= in_len - remainder + i != N;\n if should_add {\n // we want to absorb the final 'remainder' items\n sponge.absorb(input[in_len - remainder + i]);\n } else if should_check {\n assert(input[in_len - remainder + i] == 0, \"Found non-zero field after breakpoint\");\n }\n }\n sponge\n}\n\npub fn poseidon2_hash_with_separator_slice(inputs: [Field], separator: T) -> Field\nwhere\n T: ToField,\n{\n let in_len = inputs.len() + 1;\n let iv: Field = (in_len as Field) * TWO_POW_64;\n let mut sponge = Poseidon2Sponge::new(iv);\n sponge.absorb(separator.to_field());\n\n for i in 0..inputs.len() {\n sponge.absorb(inputs[i]);\n }\n\n sponge.squeeze()\n}\n\n#[no_predicates]\npub fn poseidon2_hash_bytes(inputs: [u8; N]) -> Field {\n let mut fields = [0; (N + 30) / 31];\n let mut field_index = 0;\n let mut current_field = [0; 31];\n for i in 0..inputs.len() {\n let index = i % 31;\n current_field[index] = inputs[i];\n if index == 30 {\n fields[field_index] = field_from_bytes(current_field, false);\n current_field = [0; 31];\n field_index += 1;\n }\n }\n if field_index != fields.len() {\n fields[field_index] = field_from_bytes(current_field, false);\n }\n poseidon2_hash(fields)\n}\n\n#[test]\nfn poseidon_chunks_matches_fixed() {\n let in_len = 501;\n let mut input: [Field; 4096] = [0; 4096];\n let mut fixed_input = [3; 501];\n assert(in_len == fixed_input.len()); // sanity check\n for i in 0..in_len {\n input[i] = 3;\n }\n let sub_chunk_hash = poseidon2_hash_subarray(input, in_len);\n let fixed_len_hash = std::hash::poseidon2::Poseidon2::hash(fixed_input, fixed_input.len());\n assert(sub_chunk_hash == fixed_len_hash);\n}\n\n#[test]\nfn poseidon_chunks_matches_variable() {\n let in_len = 501;\n let mut input: [Field; 4096] = [0; 4096];\n for i in 0..in_len {\n input[i] = 3;\n }\n let variable_chunk_hash = poseidon2_cheaper_variable_hash(input, in_len);\n let variable_len_hash = std::hash::poseidon2::Poseidon2::hash(input, in_len);\n assert(variable_chunk_hash == variable_len_hash);\n}\n\n#[test]\nfn existing_sponge_poseidon_chunks_matches_fixed() {\n let in_len = 501;\n let mut input: [Field; 4096] = [0; 4096];\n let mut fixed_input = [3; 501];\n assert(in_len == fixed_input.len()); // sanity check\n for i in 0..in_len {\n input[i] = 3;\n }\n // absorb 250 of the 501 things\n let empty_sponge = Poseidon2Sponge::new((in_len as Field) * TWO_POW_64);\n let first_sponge = poseidon2_absorb_chunks_existing_sponge(empty_sponge, input, 250, true);\n // now absorb the final 251 (since they are all 3s, im being lazy and not making a new array)\n let mut final_sponge = poseidon2_absorb_chunks_existing_sponge(first_sponge, input, 251, true);\n let fixed_len_hash = Poseidon2Sponge::hash(fixed_input, fixed_input.len());\n assert(final_sponge.squeeze() == fixed_len_hash);\n}\n\n#[test]\nfn poseidon_chunks_empty_inputs() {\n let in_len = 0;\n let mut input: [Field; 4096] = [0; 4096];\n let mut contructed_empty_sponge = poseidon2_absorb_chunks(input, in_len, true);\n let mut first_sponge =\n poseidon2_absorb_chunks_existing_sponge(contructed_empty_sponge, input, in_len, true);\n assert(first_sponge.squeeze() == contructed_empty_sponge.squeeze());\n}\n\n#[test]\nfn smoke_sha256_to_field() {\n let full_buffer = [\n 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,\n 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,\n 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,\n 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,\n 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,\n 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,\n 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,\n ];\n let result = sha256_to_field(full_buffer);\n\n assert(result == 0x448ebbc9e1a31220a2f3830c18eef61b9bd070e5084b7fa2a359fe729184c7);\n\n // to show correctness of the current ver (truncate one byte) vs old ver (mod full bytes):\n let result_bytes = std::hash::sha256(full_buffer);\n let truncated_field = crate::utils::field::field_from_bytes_32_trunc(result_bytes);\n assert(truncated_field == result);\n let mod_res = result + (result_bytes[31] as Field);\n assert(mod_res == 0x448ebbc9e1a31220a2f3830c18eef61b9bd070e5084b7fa2a359fe729184e0);\n}\n\n#[test]\nfn compute_l2_l1_hash() {\n // All zeroes\n let hash_result =\n compute_l2_to_l1_hash(AztecAddress::from_field(0), EthAddress::zero(), 0, 0, 0);\n assert(hash_result == 0xb393978842a0fa3d3e1470196f098f473f9678e72463cb65ec4ab5581856c2);\n\n // Non-zero case\n let hash_result = compute_l2_to_l1_hash(\n AztecAddress::from_field(1),\n EthAddress::from_field(3),\n 5,\n 2,\n 4,\n );\n assert(hash_result == 0x3f88c1044a05e5340ed20466276500f6d45ca5603913b9091e957161734e16);\n}\n\n#[test]\nfn silo_l2_to_l1_message_matches_typescript() {\n let version = 4;\n let chainId = 5;\n\n let hash = silo_l2_to_l1_message(\n ScopedL2ToL1Message {\n message: L2ToL1Message { recipient: EthAddress::from_field(1), content: 2, counter: 0 },\n contract_address: AztecAddress::from_field(3),\n },\n version,\n chainId,\n );\n\n // The following value was generated by `l2_to_l1_message.test.ts`\n let hash_from_typescript = 0x00c6155d69febb9d5039b374dd4f77bf57b7c881709aa524a18acaa0bd57476a;\n\n assert_eq(hash, hash_from_typescript);\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr"},"267":{"source":"use crate::constants::TWO_POW_64;\n\n// NB: This is a clone of noir/noir-repo/noir_stdlib/src/hash/poseidon2.nr\n// It exists as we sometimes need to perform custom absorption, but the stdlib version\n// has a private absorb() method (it's also designed to just be a hasher)\n// Can be removed when standalone noir poseidon lib exists: See noir#6679\n\ncomptime global RATE: u32 = 3;\n\npub struct Poseidon2Sponge {\n pub cache: [Field; 3],\n pub state: [Field; 4],\n pub cache_size: u32,\n pub squeeze_mode: bool, // 0 => absorb, 1 => squeeze\n}\n\nimpl Poseidon2Sponge {\n #[no_predicates]\n pub fn hash(input: [Field; N], message_size: u32) -> Field {\n Poseidon2Sponge::hash_internal(input, message_size, message_size != N)\n }\n\n pub(crate) fn new(iv: Field) -> Poseidon2Sponge {\n let mut result =\n Poseidon2Sponge { cache: [0; 3], state: [0; 4], cache_size: 0, squeeze_mode: false };\n result.state[RATE] = iv;\n result\n }\n\n fn perform_duplex(&mut self) {\n // add the cache into sponge state\n for i in 0..RATE {\n // We effectively zero-pad the cache by only adding to the state\n // cache that is less than the specified `cache_size`\n if i < self.cache_size {\n self.state[i] += self.cache[i];\n }\n }\n self.state = std::hash::poseidon2_permutation(self.state, 4);\n }\n\n pub fn absorb(&mut self, input: Field) {\n assert(!self.squeeze_mode);\n if self.cache_size == RATE {\n // If we're absorbing, and the cache is full, apply the sponge permutation to compress the cache\n self.perform_duplex();\n self.cache[0] = input;\n self.cache_size = 1;\n } else {\n // If we're absorbing, and the cache is not full, add the input into the cache\n self.cache[self.cache_size] = input;\n self.cache_size += 1;\n }\n }\n\n pub fn squeeze(&mut self) -> Field {\n assert(!self.squeeze_mode);\n // If we're in absorb mode, apply sponge permutation to compress the cache.\n self.perform_duplex();\n self.squeeze_mode = true;\n\n // Pop one item off the top of the permutation and return it.\n self.state[0]\n }\n\n fn hash_internal(\n input: [Field; N],\n in_len: u32,\n is_variable_length: bool,\n ) -> Field {\n let iv: Field = (in_len as Field) * TWO_POW_64;\n let mut sponge = Poseidon2Sponge::new(iv);\n for i in 0..input.len() {\n if i < in_len {\n sponge.absorb(input[i]);\n }\n }\n\n // In the case where the hash preimage is variable-length, we append `1` to the end of the input, to distinguish\n // from fixed-length hashes. (the combination of this additional field element + the hash IV ensures\n // fixed-length and variable-length hashes do not collide)\n if is_variable_length {\n sponge.absorb(1);\n }\n sponge.squeeze()\n }\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/noir-protocol-circuits/crates/types/src/poseidon2.nr"},"279":{"source":"use crate::{hash::poseidon2_hash, traits::ToField};\n\npub fn derive_storage_slot_in_map(storage_slot: Field, key: K) -> Field\nwhere\n K: ToField,\n{\n poseidon2_hash([storage_slot, key.to_field()])\n}\n\nmod test {\n use crate::{address::AztecAddress, storage::map::derive_storage_slot_in_map, traits::FromField};\n\n #[test]\n fn test_derive_storage_slot_in_map_matches_typescript() {\n let map_slot = 0x132258fb6962c4387ba659d9556521102d227549a386d39f0b22d1890d59c2b5;\n let key = AztecAddress::from_field(\n 0x302dbc2f9b50a73283d5fb2f35bc01eae8935615817a0b4219a057b2ba8a5a3f,\n );\n\n let slot = derive_storage_slot_in_map(map_slot, key);\n\n // The following value was generated by `map_slot.test.ts`\n let slot_from_typescript =\n 0x15b9fe39449affd8b377461263e9d2b610b9ad40580553500b4e41d9cbd887ac;\n\n assert_eq(slot, slot_from_typescript);\n }\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/noir-protocol-circuits/crates/types/src/storage/map.nr"},"292":{"source":"use crate::meta::{derive_deserialize, derive_serialize};\nuse crate::utils::field::field_from_bytes;\n\n// Trait: is_empty\n//\n// The general is_empty trait checks if a data type is is empty,\n// and it defines empty for the basic data types as 0.\n//\n// If a Field is equal to zero, then it is regarded as zero.\n// We will go with this definition for now, however it can be problematic\n// if a value can actually be zero. In a future refactor, we can\n// use the optional type for safety. Doing it now would lead to a worse devex\n// and would make it harder to sync up with the cpp code.\n// Preferred over Default trait to convey intent, as default doesn't necessarily mean empty.\npub trait Empty {\n fn empty() -> Self;\n}\n\nimpl Empty for Field {\n fn empty() -> Self {\n 0\n }\n}\n\nimpl Empty for u1 {\n fn empty() -> Self {\n 0\n }\n}\nimpl Empty for u8 {\n fn empty() -> Self {\n 0\n }\n}\nimpl Empty for u32 {\n fn empty() -> Self {\n 0\n }\n}\nimpl Empty for u64 {\n fn empty() -> Self {\n 0\n }\n}\nimpl Empty for U128 {\n fn empty() -> Self {\n U128::from_integer(0)\n }\n}\n\npub fn is_empty(item: T) -> bool\nwhere\n T: Empty + Eq,\n{\n item.eq(T::empty())\n}\n\npub fn is_empty_array(array: [T; N]) -> bool\nwhere\n T: Empty + Eq,\n{\n array.all(|elem| is_empty(elem))\n}\n\npub trait Hash {\n fn hash(self) -> Field;\n}\n\npub trait ToField {\n fn to_field(self) -> Field;\n}\n\nimpl ToField for Field {\n fn to_field(self) -> Field {\n self\n }\n}\n\nimpl ToField for bool {\n fn to_field(self) -> Field {\n self as Field\n }\n}\nimpl ToField for u1 {\n fn to_field(self) -> Field {\n self as Field\n }\n}\nimpl ToField for u8 {\n fn to_field(self) -> Field {\n self as Field\n }\n}\nimpl ToField for u32 {\n fn to_field(self) -> Field {\n self as Field\n }\n}\nimpl ToField for u64 {\n fn to_field(self) -> Field {\n self as Field\n }\n}\nimpl ToField for U128 {\n fn to_field(self) -> Field {\n self.to_integer()\n }\n}\nimpl ToField for str {\n fn to_field(self) -> Field {\n assert(N < 32, \"String doesn't fit in a field, consider using Serialize instead\");\n field_from_bytes(self.as_bytes(), true)\n }\n}\n\npub trait FromField {\n fn from_field(value: Field) -> Self;\n}\n\nimpl FromField for Field {\n fn from_field(value: Field) -> Self {\n value\n }\n}\n\nimpl FromField for bool {\n fn from_field(value: Field) -> Self {\n value as bool\n }\n}\nimpl FromField for u1 {\n fn from_field(value: Field) -> Self {\n value as u1\n }\n}\nimpl FromField for u8 {\n fn from_field(value: Field) -> Self {\n value as u8\n }\n}\nimpl FromField for u32 {\n fn from_field(value: Field) -> Self {\n value as u32\n }\n}\nimpl FromField for u64 {\n fn from_field(value: Field) -> Self {\n value as u64\n }\n}\nimpl FromField for U128 {\n fn from_field(value: Field) -> Self {\n U128::from_integer(value)\n }\n}\n\n// docs:start:serialize\n#[derive_via(derive_serialize)]\npub trait Serialize {\n fn serialize(self) -> [Field; N];\n}\n// docs:end:serialize\n\nimpl Serialize for str {\n fn serialize(self) -> [Field; N] {\n let bytes = self.as_bytes();\n let mut fields = [0; N];\n for i in 0..bytes.len() {\n fields[i] = bytes[i] as Field;\n }\n fields\n }\n}\n\n// docs:start:deserialize\n#[derive_via(derive_deserialize)]\npub trait Deserialize {\n fn deserialize(fields: [Field; N]) -> Self;\n}\n// docs:end:deserialize\n\nimpl Deserialize for str {\n fn deserialize(fields: [Field; N]) -> Self {\n str::from(fields.map(|value| value as u8))\n }\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/noir-protocol-circuits/crates/types/src/traits.nr"},"296":{"source":"use crate::traits::{Deserialize, Serialize};\n\nglobal BOOL_SERIALIZED_LEN: u32 = 1;\nglobal U8_SERIALIZED_LEN: u32 = 1;\nglobal U16_SERIALIZED_LEN: u32 = 1;\nglobal U32_SERIALIZED_LEN: u32 = 1;\nglobal U64_SERIALIZED_LEN: u32 = 1;\nglobal U128_SERIALIZED_LEN: u32 = 1;\nglobal FIELD_SERIALIZED_LEN: u32 = 1;\nglobal I8_SERIALIZED_LEN: u32 = 1;\nglobal I16_SERIALIZED_LEN: u32 = 1;\nglobal I32_SERIALIZED_LEN: u32 = 1;\nglobal I64_SERIALIZED_LEN: u32 = 1;\n\nimpl Serialize for bool {\n fn serialize(self) -> [Field; BOOL_SERIALIZED_LEN] {\n [self as Field]\n }\n}\n\nimpl Deserialize for bool {\n fn deserialize(fields: [Field; BOOL_SERIALIZED_LEN]) -> bool {\n fields[0] as bool\n }\n}\n\nimpl Serialize for u8 {\n fn serialize(self) -> [Field; U8_SERIALIZED_LEN] {\n [self as Field]\n }\n}\n\nimpl Deserialize for u8 {\n fn deserialize(fields: [Field; U8_SERIALIZED_LEN]) -> Self {\n fields[0] as u8\n }\n}\n\nimpl Serialize for u16 {\n fn serialize(self) -> [Field; U16_SERIALIZED_LEN] {\n [self as Field]\n }\n}\n\nimpl Deserialize for u16 {\n fn deserialize(fields: [Field; U16_SERIALIZED_LEN]) -> Self {\n fields[0] as u16\n }\n}\n\nimpl Serialize for u32 {\n fn serialize(self) -> [Field; U32_SERIALIZED_LEN] {\n [self as Field]\n }\n}\n\nimpl Deserialize for u32 {\n fn deserialize(fields: [Field; U32_SERIALIZED_LEN]) -> Self {\n fields[0] as u32\n }\n}\n\nimpl Serialize for u64 {\n fn serialize(self) -> [Field; U64_SERIALIZED_LEN] {\n [self as Field]\n }\n}\n\nimpl Deserialize for u64 {\n fn deserialize(fields: [Field; U64_SERIALIZED_LEN]) -> Self {\n fields[0] as u64\n }\n}\n\nimpl Serialize for U128 {\n fn serialize(self) -> [Field; U128_SERIALIZED_LEN] {\n [self.to_integer()]\n }\n}\n\nimpl Deserialize for U128 {\n fn deserialize(fields: [Field; U128_SERIALIZED_LEN]) -> Self {\n U128::from_integer(fields[0])\n }\n}\n\nimpl Serialize for Field {\n fn serialize(self) -> [Field; FIELD_SERIALIZED_LEN] {\n [self]\n }\n}\n\nimpl Deserialize for Field {\n fn deserialize(fields: [Field; FIELD_SERIALIZED_LEN]) -> Self {\n fields[0]\n }\n}\n\nimpl Serialize for i8 {\n fn serialize(self) -> [Field; I8_SERIALIZED_LEN] {\n [self as Field]\n }\n}\n\nimpl Deserialize for i8 {\n fn deserialize(fields: [Field; I8_SERIALIZED_LEN]) -> Self {\n fields[0] as i8\n }\n}\n\nimpl Serialize for i16 {\n fn serialize(self) -> [Field; I16_SERIALIZED_LEN] {\n [self as Field]\n }\n}\n\nimpl Deserialize for i16 {\n fn deserialize(fields: [Field; I16_SERIALIZED_LEN]) -> Self {\n fields[0] as i16\n }\n}\n\nimpl Serialize for i32 {\n fn serialize(self) -> [Field; I32_SERIALIZED_LEN] {\n [self as Field]\n }\n}\n\nimpl Deserialize for i32 {\n fn deserialize(fields: [Field; I32_SERIALIZED_LEN]) -> Self {\n fields[0] as i32\n }\n}\n\nimpl Serialize for i64 {\n fn serialize(self) -> [Field; I64_SERIALIZED_LEN] {\n [self as Field]\n }\n}\n\nimpl Deserialize for i64 {\n fn deserialize(fields: [Field; I64_SERIALIZED_LEN]) -> Self {\n fields[0] as i64\n }\n}\n\nimpl Serialize for [T; N]\nwhere\n T: Serialize,\n{\n fn serialize(self) -> [Field; N * M] {\n let mut result: [Field; N * M] = std::mem::zeroed();\n let mut serialized: [Field; M] = std::mem::zeroed();\n for i in 0..N {\n serialized = self[i].serialize();\n for j in 0..M {\n result[i * M + j] = serialized[j];\n }\n }\n result\n }\n}\n\nimpl Deserialize for [T; N]\nwhere\n T: Deserialize,\n{\n fn deserialize(fields: [Field; N * M]) -> Self {\n let mut reader = crate::utils::reader::Reader::new(fields);\n let mut result: [T; N] = std::mem::zeroed();\n reader.read_struct_array::(Deserialize::deserialize, result)\n }\n}\n\n#[test]\nfn test_u16_serialization() {\n let a: u16 = 10;\n assert_eq(a, u16::deserialize(a.serialize()));\n}\n\n#[test]\nfn test_i8_serialization() {\n let a: i8 = -10;\n assert_eq(a, i8::deserialize(a.serialize()));\n}\n\n#[test]\nfn test_i16_serialization() {\n let a: i16 = -10;\n assert_eq(a, i16::deserialize(a.serialize()));\n}\n\n#[test]\nfn test_i32_serialization() {\n let a: i32 = -10;\n assert_eq(a, i32::deserialize(a.serialize()));\n}\n\n#[test]\nfn test_i64_serialization() {\n let a: i64 = -10;\n assert_eq(a, i64::deserialize(a.serialize()));\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/noir-protocol-circuits/crates/types/src/type_serialization.nr"},"312":{"source":"pub mod assert_array_appended;\npub mod assert_array_prepended;\npub mod assert_combined_array;\npub mod assert_combined_transformed_array;\npub mod assert_exposed_sorted_transformed_value_array;\npub mod assert_sorted_array;\npub mod assert_sorted_transformed_value_array;\npub mod assert_split_sorted_transformed_value_arrays;\npub mod assert_split_transformed_value_arrays;\npub mod get_sorted_result;\npub mod get_sorted_tuple;\npub mod sort_by;\npub mod sort_by_counter;\n\n// Re-exports.\npub use assert_array_appended::{\n assert_array_appended, assert_array_appended_and_scoped, assert_array_appended_reversed,\n assert_array_appended_scoped,\n};\npub use assert_array_prepended::assert_array_prepended;\npub use assert_combined_array::{assert_combined_array, combine_arrays};\npub use assert_combined_transformed_array::{\n assert_combined_transformed_array, combine_and_transform_arrays,\n};\npub use assert_exposed_sorted_transformed_value_array::{\n assert_exposed_sorted_transformed_value_array,\n get_order_hints::{get_order_hints_asc, get_order_hints_desc, OrderHint},\n};\npub use assert_sorted_array::assert_sorted_array;\npub use assert_sorted_transformed_value_array::{\n assert_sorted_transformed_value_array, assert_sorted_transformed_value_array_capped_size,\n};\npub use assert_split_sorted_transformed_value_arrays::{\n assert_split_sorted_transformed_value_arrays_asc,\n assert_split_sorted_transformed_value_arrays_desc,\n get_split_order_hints::{get_split_order_hints_asc, get_split_order_hints_desc, SplitOrderHints},\n};\npub use assert_split_transformed_value_arrays::assert_split_transformed_value_arrays;\npub use get_sorted_result::{get_sorted_result, SortedResult};\npub use sort_by_counter::{sort_by_counter_asc, sort_by_counter_desc};\n\nuse crate::traits::{Empty, is_empty};\n\npub fn subarray(\n src: [Field; SRC_LEN],\n offset: u32,\n) -> [Field; DST_LEN] {\n assert(offset + DST_LEN <= SRC_LEN, \"offset too large\");\n\n let mut dst: [Field; DST_LEN] = std::mem::zeroed();\n for i in 0..DST_LEN {\n dst[i] = src[i + offset];\n }\n\n dst\n}\n\n// Helper function to convert a validated array to BoundedVec.\n// Important: Only use it for validated arrays: validate_array(array) should be true.\npub unconstrained fn array_to_bounded_vec(array: [T; N]) -> BoundedVec\nwhere\n T: Empty + Eq,\n{\n let len = array_length(array);\n BoundedVec::from_parts_unchecked(array, len)\n}\n\n// Helper function to find the index of the first element in an array that satisfies a given predicate. If the element\n// is not found, the function returns N as the index.\npub unconstrained fn find_index_hint(\n array: [T; N],\n find: fn[Env](T) -> bool,\n) -> u32 {\n let mut index = N;\n for i in 0..N {\n // We check `index == N` to ensure that we only update the index if we haven't found a match yet.\n if (index == N) & find(array[i]) {\n index = i;\n }\n }\n index\n}\n\n// Routine which validates that all zero values of an array form a contiguous region at the end, i.e.,\n// of the form: [*,*,*...,0,0,0,0] where any * is non-zero. Note that a full array of non-zero values is\n// valid.\npub fn validate_array(array: [T; N]) -> u32\nwhere\n T: Empty + Eq,\n{\n let mut seen_empty = false;\n let mut length = 0;\n for i in 0..N {\n if is_empty(array[i]) {\n seen_empty = true;\n } else {\n assert(seen_empty == false, \"invalid array\");\n length += 1;\n }\n }\n length\n}\n\n// Helper function to count the number of non-empty elements in a validated array.\n// Important: Only use it for validated arrays where validate_array(array) returns true,\n// which ensures that:\n// 1. All elements before the first empty element are non-empty\n// 2. All elements after and including the first empty element are empty\n// 3. The array forms a contiguous sequence of non-empty elements followed by empty elements\npub fn array_length(array: [T; N]) -> u32\nwhere\n T: Empty + Eq,\n{\n // We get the length by checking the index of the first empty element.\n\n /// Safety: This is safe because we have validated the array (see function doc above) and the emptiness\n /// of the element and non-emptiness of the previous element is checked below.\n let length = unsafe { find_index_hint(array, |elem: T| is_empty(elem)) };\n if length != 0 {\n assert(!is_empty(array[length - 1]));\n }\n if length != N {\n assert(is_empty(array[length]));\n }\n length\n}\n\npub fn array_concat(array1: [T; N], array2: [T; M]) -> [T; N + M] {\n let mut result = [array1[0]; N + M];\n for i in 1..N {\n result[i] = array1[i];\n }\n for i in 0..M {\n result[i + N] = array2[i];\n }\n result\n}\n\npub fn array_merge(array1: [T; N], array2: [T; N]) -> [T; N]\nwhere\n T: Empty + Eq,\n{\n let mut result: [T; N] = [T::empty(); N];\n let mut i = 0;\n for elem in array1 {\n if !is_empty(elem) {\n result[i] = elem;\n i += 1;\n }\n }\n for elem in array2 {\n if !is_empty(elem) {\n result[i] = elem;\n i += 1;\n }\n }\n result\n}\n\n// Helper fn to create a subarray from a given array\npub fn array_splice(array: [T; N], offset: u32) -> [T; M]\nwhere\n T: Empty,\n{\n assert(M + offset <= N, \"Subarray length larger than array length\");\n let mut result: [T; M] = [T::empty(); M];\n for i in 0..M {\n result[i] = array[offset + i];\n }\n result\n}\n\npub fn check_permutation(\n original_array: [T; N],\n permuted_array: [T; N],\n original_indexes: [u32; N],\n)\nwhere\n T: Eq + Empty,\n{\n let mut seen_value = [false; N];\n for i in 0..N {\n let index = original_indexes[i];\n let original_value = original_array[index];\n assert(permuted_array[i].eq(original_value), \"Invalid index\");\n assert(!seen_value[index], \"Duplicated index\");\n seen_value[index] = true;\n }\n}\n\n#[test]\nfn smoke_validate_array() {\n let valid_array: [Field; 0] = [];\n assert(validate_array(valid_array) == 0);\n\n let valid_array = [0];\n assert(validate_array(valid_array) == 0);\n\n let valid_array = [3];\n assert(validate_array(valid_array) == 1);\n\n let valid_array = [1, 2, 3];\n assert(validate_array(valid_array) == 3);\n\n let valid_array = [1, 2, 3, 0];\n assert(validate_array(valid_array) == 3);\n\n let valid_array = [1, 2, 3, 0, 0];\n assert(validate_array(valid_array) == 3);\n}\n\n#[test(should_fail_with = \"invalid array\")]\nfn smoke_validate_array_invalid_case0() {\n let invalid_array = [0, 1];\n let _ = validate_array(invalid_array);\n}\n\n#[test(should_fail_with = \"invalid array\")]\nfn smoke_validate_array_invalid_case1() {\n let invalid_array = [1, 0, 0, 1, 0];\n let _ = validate_array(invalid_array);\n}\n\n#[test(should_fail_with = \"invalid array\")]\nfn smoke_validate_array_invalid_case2() {\n let invalid_array = [0, 0, 0, 0, 1];\n let _ = validate_array(invalid_array);\n}\n\n#[test]\nfn test_empty_array_length() {\n assert_eq(array_length([0]), 0);\n assert_eq(array_length([0, 0, 0]), 0);\n}\n\n#[test]\nfn test_array_length() {\n assert_eq(array_length([123]), 1);\n assert_eq(array_length([123, 0, 0]), 1);\n assert_eq(array_length([123, 456]), 2);\n assert_eq(array_length([123, 456, 0]), 2);\n}\n\n#[test]\nfn test_array_length_invalid_arrays() {\n // Result can be misleading (but correct) for invalid arrays.\n assert_eq(array_length([0, 0, 123]), 0);\n assert_eq(array_length([0, 123, 0]), 0);\n assert_eq(array_length([0, 123, 456]), 0);\n assert_eq(array_length([123, 0, 456]), 1);\n}\n\n#[test]\nunconstrained fn find_index_greater_than_min() {\n let values = [10, 20, 30, 40];\n let min = 22;\n let index = find_index_hint(values, |v: Field| min.lt(v));\n assert_eq(index, 2);\n}\n\n#[test]\nunconstrained fn find_index_not_found() {\n let values = [10, 20, 30, 40];\n let min = 100;\n let index = find_index_hint(values, |v: Field| min.lt(v));\n assert_eq(index, 4);\n}\n\n#[test]\nfn test_array_concat() {\n let array0 = [1, 2, 3];\n let array1 = [4, 5];\n let concatenated = array_concat(array0, array1);\n assert_eq(concatenated, [1, 2, 3, 4, 5]);\n}\n\n#[test]\nfn check_permutation_basic_test() {\n let original_array = [1, 2, 3];\n let permuted_array = [3, 1, 2];\n let indexes = [2, 0, 1];\n check_permutation(original_array, permuted_array, indexes);\n}\n\n#[test(should_fail_with = \"Duplicated index\")]\nfn check_permutation_duplicated_index() {\n let original_array = [0, 1, 0];\n let permuted_array = [1, 0, 0];\n let indexes = [1, 0, 0];\n check_permutation(original_array, permuted_array, indexes);\n}\n\n#[test(should_fail_with = \"Invalid index\")]\nfn check_permutation_invalid_index() {\n let original_array = [0, 1, 2];\n let permuted_array = [1, 0, 0];\n let indexes = [1, 0, 2];\n check_permutation(original_array, permuted_array, indexes);\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr"},"315":{"source":"pub struct Reader {\n data: [Field; N],\n offset: u32,\n}\n\nimpl Reader {\n pub fn new(data: [Field; N]) -> Self {\n Self { data, offset: 0 }\n }\n\n pub fn read(&mut self) -> Field {\n let result = self.data[self.offset];\n self.offset += 1;\n result\n }\n\n pub fn read_u32(&mut self) -> u32 {\n self.read() as u32\n }\n\n pub fn read_bool(&mut self) -> bool {\n self.read() as bool\n }\n\n pub fn read_array(&mut self) -> [Field; K] {\n let mut result = [0; K];\n for i in 0..K {\n result[i] = self.data[self.offset + i];\n }\n self.offset += K;\n result\n }\n\n pub fn read_struct(&mut self, deserialise: fn([Field; K]) -> T) -> T {\n let result = deserialise(self.read_array());\n result\n }\n\n pub fn read_struct_array(\n &mut self,\n deserialise: fn([Field; K]) -> T,\n mut result: [T; C],\n ) -> [T; C] {\n for i in 0..C {\n result[i] = self.read_struct(deserialise);\n }\n result\n }\n\n pub fn finish(self) {\n assert(self.offset == self.data.len(), \"Reader did not read all data\");\n }\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.71.0/noir-projects/noir-protocol-circuits/crates/types/src/utils/reader.nr"}}} \ No newline at end of file +{"noir_version":"1.0.0-beta.1+4ca7394b2efd7aef","name":"SimpleLogging","functions":[{"name":"add_to_counter_public","is_unconstrained":true,"custom_attributes":["public","internal"],"abi":{"parameters":[{"name":"counter_id","type":{"kind":"field"},"visibility":"private"}],"return_type":null,"error_types":{"206160798890201757":{"error_kind":"string","string":"Storage slot 0 not allowed. Storage slots must start from 1."},"5019202896831570965":{"error_kind":"string","string":"attempt to add with overflow"},"10176877060487216746":{"error_kind":"string","string":"Function add_to_counter_public can only be called internally"},"13699457482007836410":{"error_kind":"string","string":"Not initialized"},"16761564377371454734":{"error_kind":"string","string":"Array index out of bounds"},"17843811134343075018":{"error_kind":"string","string":"Stack too deep"}}},"bytecode":"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","debug_symbols":"7Z3dTiM7DMffpde9SGwnTvZVVkcIWHZVqQLEx5GOEO9+poiZljjtyFm6Yie+QZTm39g/px7PkPG8rH7cXD3/utjc/rx7XH37/rLa3l1fPm3ubodXL6/r1dXDZrvd/Lo4/PPK7X54eBv/eH95u3v5+HT58LT65mN269XN7Y/hV3Zu+ISfm+3N6luE13/WK48NGmrQhAZNbNBwgyY1aLJeA65B4xs0DesAGtYBaNfBWg52LoyDHYRpcM6VwUTE74OJQpwGs68MTjh9ckLwh4N3podPMD3BOHiw/c+ZHj/BdPIT9ThD3Yc4DY6eT5ueMY+DMyGVpvOnmu7dB9N3E6RzT5DPPAG6356AIowTDL/mubXGMK21xEXA0P++NZ+38rEhr2FDXsOG4xtWE0oAfJcEglIR1QpWK5JakbUKcmqFVytArUC1gtQKdcxJHXNSx5zUMSd1zIM65kEd8zAX85BnEq2n/QE67lObp9phjjGNn8zk6HSeYj8d+xk+5qmaHQ5xn/FjLNJamFuqB0fodzT1pcpj7gyZSkVQK6JawWpFUiuyVhGdWuHVClArUK1QxzyqYx7VMY/qmEd1zONMzKOHmUSAEMfvHwaYSwQJx9GcQppJBBHzOHioD+YSwWFG8gmLRJDqdceQMfaieGB9dY40Dc572yG5twnCuSeI556Azz1BOvcE+cwTZHfuCfy5J4BzT3DkiDtKAuyrBYjVcziVLWEcDAfXCXa2VM6ACMaEkogPzAi1T8bpkwncaZPBZxqtgIOMOQzeESEjUhAJRqQgEo1IQYSNSEEkGZGCSDYiH4kM1/wNSYnEG5ISCRiSEonVrQIJGZISSb1yjW66nui7QxINSYmEDUmJpF68Tpr4UdIFkmxICiTeGZISiTckJRIwJCUSNCQlEjIkJZJgSEok0ZCUSNiQlEisehVIrHotkYBVrwKJVa8CyWf8B/5v8BM78ZM68TN04mfsxE/uxM/UiZ+5Dz/RdeKn78TPTuoh7KQewk7qIeykHsJO6iHspB7CTuoh7KQeok7qIeqkHqLF5CHAvZ8USj/r97kC+9EaYMTXxV0cPO7fG5QjTQHidJNrTAvcOzQDBQyKhIIGRUIhgyKh1E9UmCc/OYfuoESDIqGwQZFQkkGRULJBEVDq7TB6h+INioQCBkVCQYMioZBBkVCsoq1AsYq2AsUq2goUq2grUKyilVDYKtoKFKtoK1DqFW32U1O2DP1BQYMioZBBkVDqFa2fOn57oDTjJ+B4fznQ3ppq10bmcSinj81b34yJX8kY/krGpC9kTFrMhjJ0kxXoqfxufErrzr/Bz8VsKJvxczEbymb8XMxGjhk/F7OhbMbPxWwoO+3nsSa3UwEzuJyWV6BBhgmKE7uVjjXm7RtK/aTPH7TkDwvcbjEDBQ2KhEIGRUIJBkVCOXLyGadnmQ0FR3dQ6qUHuempSeR6WylQb3XbOxRvUCQUMCgSSr1O2T8byYfguoNCBkVCCQZFQokGRUJhgyKhJIMioWSDIqDU29/2DsUbFAkFDIqEYhVtBQrVoUyPpvYhL7AH3wyUYFAklGhQJBQ2KBJKMigSSjYoAgo4gyKheIMiodSLN9xvC0Xs7hrtkd6ynUMJBkVCiQZFQmGDIqEkgyKhZIMioBzptNs5FG9QJBQwKBKKVbQVKGRQJJQjFS3xBCV2d+H6SN/hzqGwQZFQkkGRULJBEVCO9EruHIo3KBKKbRmtQEGDIqGQQZFQgkGRUJbT2f2kn/XeuoyjMUwoJNVqJdM4TQ5ilnq3zdMSr5eAXoLKW0XfRNQiCi2i2CLiFlFqEeUGEbsWkW8RQYuoZUVwy4rglhXBLSuCW1YEt6yI5NTpJNW/6G58HkUGKdF/0esNO07PEvUS1kuSXqJPwFmfgLM+AWd9XOp3YJ+WkF4S9JJ69MO4kjODkLBekvSSrJVg/e7L0xKvl4BeMhf9ikQdfXRBL4l6CeslSS9Rf/fRO73E6yWgl6Beoo++10ff66Pv9dH3yui/Dq/+vXzYXF5tbx4Hxe7N59vrp83d7fvLp//ux3euHjbb7ebXxf3D3fXNj+eHm4vt3fXuvZV7//EdIa2R8mDK2wphv+a4e7GLPQa3xgDDnMO8/wM=","brillig_names":["add_to_counter_public"]},{"name":"constructor","is_unconstrained":true,"custom_attributes":["public","initializer"],"abi":{"parameters":[],"return_type":null,"error_types":{"2233873454491509486":{"error_kind":"string","string":"Initializer address is not the contract deployer"},"5019202896831570965":{"error_kind":"string","string":"attempt to add with overflow"},"16761564377371454734":{"error_kind":"string","string":"Array index out of bounds"},"17618083556256589634":{"error_kind":"string","string":"Initialization hash does not match"},"17843811134343075018":{"error_kind":"string","string":"Stack too deep"}}},"bytecode":"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","debug_symbols":"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","brillig_names":["constructor"]},{"name":"compute_note_hash_and_optionally_a_nullifier","is_unconstrained":true,"custom_attributes":[],"abi":{"parameters":[{"name":"contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::aztec_address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"},{"name":"nonce","type":{"kind":"field"},"visibility":"private"},{"name":"storage_slot","type":{"kind":"field"},"visibility":"private"},{"name":"note_type_id","type":{"kind":"field"},"visibility":"private"},{"name":"compute_nullifier","type":{"kind":"boolean"},"visibility":"private"},{"name":"serialized_note","type":{"kind":"array","length":0,"type":{"kind":"field"}},"visibility":"private"}],"return_type":{"abi_type":{"kind":"array","length":4,"type":{"kind":"field"}},"visibility":"public"},"error_types":{"16541607464495309456":{"error_kind":"fmtstring","length":16,"item_types":[]},"17843811134343075018":{"error_kind":"string","string":"Stack too deep"}}},"bytecode":"H4sIAAAAAAAA/9VZ227aQBBdsI2xiYHCH0TqWyvZhOsbUi/5DpTAF/QD/NCX9qvLih37MExUJGaisFK0Zmd95uyZ2Ys3HXcq/eNfJzzHoe65y0J9tqEubyuVIlZpybNzJzy7d8IzuhOesSLPjsDT1zTfEneac6k7zcemEV/yAY7gJfc/AHD2N9RZqLtgVwxIlQmD1MJfl/OXzJ0XZf5PWcBMbfAXhN+3wS+J97e6xcexkN8o1M91q+UzvONLEZ4xeQmXbF2wfWe2CGw/mA1z+CezYd4TJ9KtB2NRzKu1dVxobCmMrfNG7VyrHbaR1rkzzdGKYp4xPpw/8SmoT93y6TFbDLaM2RKwkf6+foR+PPYp9PsK7TwnI3eZw2SnmKPWFjkVG+Afy1zSncckrs99ow11j0HPR6aPxV6B+ljo7/WZvsGfnn1Ja9eUiOmJGpFmfezPbBnY4vrcTx5+x+AHsYhHwvp/Cb9Hoe7BO/T+WPDfY/7PeAttqBHHioQ26u/n5OfwPHCn/PlN/d3lOqV3mF7OpTVbD3/V4Gc2/A+En9vgLwl/YIPfnGUeTPBnJeEXNvw3hD+0yZ/mLDmy4b8n/LEJ/nxP++4n15ZmfQjPE2jXW7ur6pozEfrPGVerM9GE8eH64P7rbVOB61iw8RhOBT9TwY+ElSliPShijT7oGPuKWANFrKEilmYcU0UsTb1yRaxCEUsz7zX1ojhK5zRftqEubyzSOU0Rv5LOaZrf7qQ15VcsaIjjS1j/X0zngQnPakZ7Ds118oG+CyPf1+7X5L8Q+BDvXLDdchm7X6wPm/ViczySVcvZpolnwbjyNvwmwvUY+0t7v3TuU9S6lL77h6CrLzHYCmZLwEYcpe/+oRH/a/RH/2PBxvf/a2M5cZf74YCNG++4tipjbu//pLt54/Vrce3cJP+5u1yv3+t+EfXhZ+lc4DoWbPx8kgt+csHPPWLxO3rU0Oc16RTXrV0rlqt1+48tWosSd37v75j/hPX/E37j2Ki+Zc0/rHbV4Wl32C12r6/zl92E4fvSBZ3+Ab+1O0oNHwAA","debug_symbols":"tdfRioQgFAbgd/HaC49aZq+yLIOVDYJYWC0s0buvDbO7w8zl8N8EJ06fIf7I2dngu+16CWmcFtZ+7CxOvVvDlEq1H5x1OcQYrpfH10ycD6tu/cvs0lkuq8sra5XkzKeBtVqUr8cQPWtrefCXRvPbaMxfYyWPT86sRsEVCq5RsEHBDQq2IJiEgMkEkyVMVjBZw+QKJtcw2cDkBibDMkiwDBIsgwTLIMEySLAMEiyD9F4Grbo3lm19oQ2ObnC0hdFS4GjC0RJHKxytcXSFo3FplLg0SlwaJSiNR6m+XA6ui/4+M41b6h9GqPV79k/T1Jyn3g9b9udc9T9SnYdYaa717RYvBZX/I2XKImWhHw==","brillig_names":["compute_note_hash_and_optionally_a_nullifier"]},{"name":"public_dispatch","is_unconstrained":true,"custom_attributes":["public"],"abi":{"parameters":[{"name":"selector","type":{"kind":"field"},"visibility":"private"}],"return_type":null,"error_types":{"206160798890201757":{"error_kind":"string","string":"Storage slot 0 not allowed. Storage slots must start from 1."},"2233873454491509486":{"error_kind":"string","string":"Initializer address is not the contract deployer"},"5019202896831570965":{"error_kind":"string","string":"attempt to add with overflow"},"10176877060487216746":{"error_kind":"string","string":"Function add_to_counter_public can only be called internally"},"13699457482007836410":{"error_kind":"string","string":"Not initialized"},"16541607464495309456":{"error_kind":"fmtstring","length":16,"item_types":[]},"16761564377371454734":{"error_kind":"string","string":"Array index out of bounds"},"17618083556256589634":{"error_kind":"string","string":"Initialization hash does not match"},"17843811134343075018":{"error_kind":"string","string":"Stack too deep"}}},"bytecode":"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","debug_symbols":"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","brillig_names":["public_dispatch"]},{"name":"sync_notes","is_unconstrained":true,"custom_attributes":[],"abi":{"parameters":[],"return_type":null,"error_types":{"17843811134343075018":{"error_kind":"string","string":"Stack too deep"}}},"bytecode":"H4sIAAAAAAAA/9VTvQ6CMBBu+YmCMqiJbia+QREMjCbuvkMDMuqAixuPLjXX9FKbMLQ18Uuaa+Hy/ZSDEgUKNSIWkCQHqAnUAL0Px3WGM7NDnmi6LvlrVhaJIZ9D/x9+6sm/gOT3dP9sBjyXQfHjLFJ3Pq4UzYSvzPKb+cy8mci5+kHOEcdM08aghmehoYci3zvYZ4Y+iQVR/3Q0uM9V1YxJvRD4Y/LtHevHWv8WzqnmX9TIwmdX8bwreMdPvG3Lhq81foEA3dM/z8Ie9lOzgDMuiZqN/nVvro/nrScTECRvfuFT84YGAAA=","debug_symbols":"nZLLCoMwEEX/ZdYuMvHV5lekSNQogZBIjIUi/nujSGuLm2QzcId77uos0IlmHmqpezMBqxZQpuVOGu3TsibQWKmUHOrzG8h2EPf+NHK9xclx64ClNAGhO2AZ8XQvlQBW0PWRANLAfhrYzwL7eVifXu4jIbfyQJAgZh8K03zH8jisiMPKOOwWhaV4jWFZfLF7/outPj65lbxR4pCsn3V7cs69RvGn32hNK7rZik3Ek4P+VlgmlPpZP/0G","brillig_names":["sync_notes"]},{"name":"increase_counter_public","is_unconstrained":true,"custom_attributes":["public"],"abi":{"parameters":[{"name":"counter_id","type":{"kind":"field"},"visibility":"private"}],"return_type":null,"error_types":{"13699457482007836410":{"error_kind":"string","string":"Not initialized"},"16761564377371454734":{"error_kind":"string","string":"Array index out of bounds"},"17843811134343075018":{"error_kind":"string","string":"Stack too deep"}}},"bytecode":"H4sIAAAAAAAA/+1YS2/TQBBex7ETJ40awQUJid/gPNqktyDUG4IDgruJbRSpL/WB4IDkIxeQkLiBxAFx4YYE/49utdN+Hk/SlO6mILGStd7d8Tcz3+yOd9dTF8UzdZ21lSAzMXV8vdKziBWLhi4qJPPL1JGpazDuW3Q2Ynpt4o/j4TAS/LNo/yAymC75IUwH+HHD4DwoLvC5L7p0TBvnEH3TPH3api9ici7i6ZDv+LZgP+nSfr5lfPjAhzenVqocPyo1xhlPMhNLPnVVdQ7VV+DHv+xDYN+HvuQD6Vk7fbrmPXm5+/hgup9m99P0MDs68phfkv1SuQpmcAXMOxzz0cnOziyfZYfbr2ZHxxXsUMCm95qSfeN2oRwWKT/qMjF1fL3SC5gP90ytc8H7BTZ41mwYxXxO2sXvn+OHTvA3p4TfcMPPBuE33difE37kBr9P+C03+CPKj/SPJh04d9eg3+L/dLxM/kX9LWar7f2Ux/SRPZwfyjfEXUewtSuM8RzQEfR0BD0SVsMiVmQRK7CIFVrEalrEorW4aG8h5eWbWDukv6Wqc9DF2gkEXn2BV+IuFGztCmO4/8Ux1BMKev5j/Z1YHdamcakmPbyP60E7Sd71GdnxOh9J+y+b65biIJ3rtc4n0E+PMv76wrcBjKP8AWA+M+/rTAZjKJ17bfLqMdt98AfnJD/7NdzYM1i0tpAD0n/dcy3qWtW/QfJN+jesKgfdZEyRa76XawjyUt6jPYlfVLForA5jIRsLiionep/0gdmzbNzWVTVW9K1jrvs8P6GtGHvSr/fpd837+V3F9u7s+Oletjc9fH1wnKUP918oVviVBF5BzEtl0jVGTZVNJZOWvZKRlrhU9LFlmTTrKCznaZa23/N+Gw0YR/kTU+v2Z+a/tEykYxq3AeXRbz6NcYk2F3yHS0G6bnDBZwR8SXwi3yj/xtTIp5RGPPBHl3rhxJ+xtuML2MH5DJhNUgylVMR5QnmMDf9N4FGYp2UptaC+kGFJ21Fpu0W4uN1yyftoHMekk2IeqDKPiukPmPw708ZrKQV+T/7QznyU9PJBkicbSZoOp8kthq+Au7YD/c+zXjbI83yQJcN8M79UP/U3iotxn3F1xp95p7XWRHk2FsFYvSjrb5l2HfQgFtkRMPlPpr1u6hC+oe+7gv6Q6S/ZLfThvOZYvtBH8nrufzTvLuKajbfSeCvPkl6v10/j7LK4SjxhftSFuMZYhIJvAZP/Cj5/M+98S4b6tNzPBXLenPoMQ+irF+U+KUY4d0medLeKqo001oYxzN26rJk28oVYZEfA5H+YNsUE5xt93xX0N5n+kt1CH5+7bUG+Lcjr+HwnPFOj77aPUmc6GT72cdto7uh5/RsllbLkwCIAAA==","debug_symbols":"zZrbjuIwDIbfpde9iGM7iXmV1WrEoYwqIUAcVloh3n1bNO2yFHU1HtLxDSJgu1/bv7/TNpdiVS3O72/1dr07FrMfl2KzW85P9W7bjC7Xslgc6s2mfn+7/7lw7Qf4W/xxP9+2w+NpfjgVMwjiyqLarpqv0bmmwrreVMUs+OvPsgBU5JAihxU5QZETFTlJkSOfz/FOkQOKHIUOvEIH/rM6KIfBznEX7Dz3wSJPgokofgQTceiDIzwJTthXTujhPrhF5xegJ98FN+zToYcXoBP0Rz3856gDhz44QBxHF5QuWAjpET2+FB3cP+jtBlLuDUjmDaDCI1DhEajwCFR4BCp6BSp6BSp6BSp6BSp6BSp6BSl0QAodkEIHpNABKXRACh2QQgek0AEpdEAKHbBCB6zQASt0wAodsEIHrNABP9VBhK5lR+Rxm06ha9hJ/HjTo8Spa+6JpQ/2gjeUaAcl2UERMyjB2UEBOyjeDgraQSE7KGwHxY7bBjtuG+y4bbDjttGO20Y7bhvtuG2047bRjttGO24b7bhttOO2aVLZJu5RJAxQpjxBAt3jJBLvBiivO0HiHh9FppSzuGQsLi5ncchZ3OcsjjmLU87inLN4yFk85xUqOa9QyXmFNm+GslaHrNV91uqYtTplrf7l65T7F0yOxlujcN+lJUAYoAQ7KNEOSrKDImZQ4LkZJeqmaXf1n6K88AUwwKT3iqMzXYApZ93isZ/qIgxZyBALG2IJhliiIZZkiEXssHj3TSzkhixTPqIbv5UG7w2xoCEWMsTChljsPAYCHw2xJEMsYocFnSEWQ76LhnwXrfjutRn+mh/q+WJTfawMX5+3y7uF4qff++phzfj+sFtWq/OhaleP/1043uoOWEpIrtnHdg+BuATm211YO8RQAsFtonL71zdDahgajj8=","brillig_names":["increase_counter_public"]},{"name":"get_counter_value","is_unconstrained":true,"custom_attributes":[],"abi":{"parameters":[{"name":"counter_id","type":{"kind":"field"},"visibility":"private"}],"return_type":{"abi_type":{"kind":"field"},"visibility":"public"},"error_types":{"206160798890201757":{"error_kind":"string","string":"Storage slot 0 not allowed. Storage slots must start from 1."},"5019202896831570965":{"error_kind":"string","string":"attempt to add with overflow"},"16761564377371454734":{"error_kind":"string","string":"Array index out of bounds"},"17843811134343075018":{"error_kind":"string","string":"Stack too deep"}}},"bytecode":"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","debug_symbols":"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","brillig_names":["get_counter_value"]},{"name":"process_log","is_unconstrained":true,"custom_attributes":[],"abi":{"parameters":[{"name":"log_plaintext","type":{"kind":"struct","path":"std::collections::bounded_vec::BoundedVec","fields":[{"name":"storage","type":{"kind":"array","length":18,"type":{"kind":"field"}}},{"name":"len","type":{"kind":"integer","sign":"unsigned","width":32}}]},"visibility":"private"},{"name":"tx_hash","type":{"kind":"field"},"visibility":"private"},{"name":"unique_note_hashes_in_tx","type":{"kind":"struct","path":"std::collections::bounded_vec::BoundedVec","fields":[{"name":"storage","type":{"kind":"array","length":64,"type":{"kind":"field"}}},{"name":"len","type":{"kind":"integer","sign":"unsigned","width":32}}]},"visibility":"private"},{"name":"first_nullifier_in_tx","type":{"kind":"field"},"visibility":"private"},{"name":"recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::aztec_address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"return_type":null,"error_types":{"16541607464495309456":{"error_kind":"fmtstring","length":16,"item_types":[]},"17843811134343075018":{"error_kind":"string","string":"Stack too deep"}}},"bytecode":"H4sIAAAAAAAA/92caVPbMBCGHbABB0LC0fukNy1tHZKQpCctve8L+jlTyJ9oP7j9E7T/tnlBSzZCnaGDNOWtZzxOvMruo7Usr6VVCtH2ttbbC+ZzbI6j5ojz09HgJmWXzTHb31b1qCsLxVggYBwiYBwmYIwJGBMCxhECxlECxjECxpSAsUjAOE7AOEHAWCJgnCRgLBMwVggYpwIwhuCcJuGc8cipY/tQvLPRwW+jhwgYDxMwHiFgPErAeIyA8TgB4wkCxpMEjKcIGE8TMJ4hYDxLwDhHwHiOgPE8AeMFAsaLBIyXCBgvEzBeIWCcJ2C8SsB4jYBxgYDxOgHjDQLGmwSMGQFjlYBxkYCxRsBYJ2BsEDAuETA2CRhbBIxtAsZbBIy3CRjvEDDeJWC8R8B4n4BxmYDxAQHjQwLGFQLGRwSMjwkYnxAwPiVgfEbA+JyA8QUB40sCxlcEjK8JGN8QML4lYHxHwPiegPEDAePHAIwhOD+RcK6ScK4F4ow+W9BDvR0Lt7AwCguPsLAHC2ewMAULP7CwAgsXsDAAifdIbEfieKW3I/EZScVI2EUSLJJMkcSJJEkkISLJD0l0SFJDEhiSrJDEhCShs719rrcjiQRJGkiCQJIBJvExSY5JaEzyYhIVk5SYBMQkGyaxMEmEWmGSA5MIGKTHIDgGmTGIi0FSDEJikA+DaBikwiAQBlkwiCGDBHjJxUskXtLwEoSXDATxCJIRhCLIQxCFIAVBAB6yeIjhIYFOGJ0cOhHcpLgB0LjWoj9v0kh+mGNqjkNK7nERXTW17PrU38randRRP4/8tdToHAuiv9EU/WkY/kwW2q7kff26LmJ32BxX874vV/NBJimzqcpsWmWkPmGud70W1l/VxZLlo0jVRWwXw9iuFSx7+rpomdgvRiHb5vaiZG1PeGz/SN9RkjJ5n6dgyeJ8dz1EliiZXF/YmVfl7LY1ZsmEBZu035LyjWxrRibXNFY6/bXX0Pd3Pft37bVe/R/ba2zJ4nx3Pf62veq2ZbfXJOpv0peKbETJflqyUSX7lfdt1825sP3w9nNX32++n1szDn5tC9to3veBtLthdS5RPtvyjy5vyVIli/NBO0XzPVZ2tC7hSKzyNfO9bI4j6jfy+4rD/ohlf4Dbcc72S+oonzrKo30tmM+Ir9F+vkn5aPe9in3ZfM/2tS21Xf2iP/3Nmqvv88i/IfrHg+iv7+ifCMNfF/2lMP7f0T8Zhr8r+sth9C+J/koY/Q3RPxVE/+JOXKD/XMeOC2bUeY9x7J7jArFftFhDxQUzFo/tHx0XQDbrYK04ZHYfMOuwM+uw49I16VHXlEddxQNax5JHXRWPulKPunxexwmPunz6q+xR15hHXT7bvU9/yXUMOz6VZa44LQqgvxhG/07fL320fhfTdRL7iVX+q+XniSB+7o87SX+mfeGKpXza3uvzWuyXHDzCXXTI9vOHZxuNVrfdarR7IX11abGdFSz9wmqf0+9Eun/R5V3Pflfc59HXmWvMoaz8ii1WsklLliiZMOoxB1dc7JN/L/7X9isOmd0/7/VaTkeDbU3fj+NR/36Oc/91b7a2/8hli9HoT6LBMcXIsp9Y5b+b73Zft997pNvsVLu1TrfT6Kyv1790pi392ofw02+mXHNgmVMAAA==","debug_symbols":"tZbLCoMwEEX/ZdZZOFOtrb9SSokaJRCiRC0U8d8bpQ9p13cTuGFyZnXCnak25dTerG+6gYrLTK6r9Gg7H9O8KCqDdc62t/01JevBSbI9GHrt1zyMOoxUHESR8TUVaRKfN9YZKo6yqL/B/D2Y55/BTJarimSGkQVGPsDIKYycwchHGDmHkU8w8hlFZpiDDHOQYQ4yzEGGOcgwBxnmIMMcZJiDDHNQYA4KzEHBOLjEdNfB6tKZV4FoJl/t+sT46M1PtehDV5l6CmYtGd9+sbqcssp4+0FjYEkVyzkuiYue","brillig_names":["process_log"]}],"outputs":{"structs":{"functions":[{"kind":"struct","path":"SimpleLogging::increase_counter_public_abi","fields":[{"name":"parameters","type":{"kind":"struct","path":"SimpleLogging::increase_counter_public_parameters","fields":[{"name":"counter_id","type":{"kind":"field"}}]}}]},{"kind":"struct","path":"SimpleLogging::constructor_abi","fields":[{"name":"parameters","type":{"kind":"struct","path":"SimpleLogging::constructor_parameters","fields":[]}}]},{"kind":"struct","path":"SimpleLogging::add_to_counter_public_abi","fields":[{"name":"parameters","type":{"kind":"struct","path":"SimpleLogging::add_to_counter_public_parameters","fields":[{"name":"counter_id","type":{"kind":"field"}}]}}]}]},"globals":{"storage":[{"kind":"struct","fields":[{"name":"contract_name","value":{"kind":"string","value":"SimpleLogging"}},{"name":"fields","value":{"kind":"struct","fields":[{"name":"counters","value":{"kind":"struct","fields":[{"name":"slot","value":{"kind":"integer","sign":false,"value":"0000000000000000000000000000000000000000000000000000000000000001"}}]}}]}}]}]}},"file_map":{"26":{"source":"use crate::default::Default;\nuse crate::hash::Hasher;\n\ncomptime global RATE: u32 = 3;\n\npub struct Poseidon2 {\n cache: [Field; 3],\n state: [Field; 4],\n cache_size: u32,\n squeeze_mode: bool, // 0 => absorb, 1 => squeeze\n}\n\nimpl Poseidon2 {\n #[no_predicates]\n pub fn hash(input: [Field; N], message_size: u32) -> Field {\n Poseidon2::hash_internal(input, message_size, message_size != N)\n }\n\n pub fn new(iv: Field) -> Poseidon2 {\n let mut result =\n Poseidon2 { cache: [0; 3], state: [0; 4], cache_size: 0, squeeze_mode: false };\n result.state[RATE] = iv;\n result\n }\n\n fn perform_duplex(&mut self) {\n // add the cache into sponge state\n for i in 0..RATE {\n // We effectively zero-pad the cache by only adding to the state\n // cache that is less than the specified `cache_size`\n if i < self.cache_size {\n self.state[i] += self.cache[i];\n }\n }\n self.state = crate::hash::poseidon2_permutation(self.state, 4);\n }\n\n fn absorb(&mut self, input: Field) {\n assert(!self.squeeze_mode);\n if self.cache_size == RATE {\n // If we're absorbing, and the cache is full, apply the sponge permutation to compress the cache\n self.perform_duplex();\n self.cache[0] = input;\n self.cache_size = 1;\n } else {\n // If we're absorbing, and the cache is not full, add the input into the cache\n self.cache[self.cache_size] = input;\n self.cache_size += 1;\n }\n }\n\n fn squeeze(&mut self) -> Field {\n assert(!self.squeeze_mode);\n // If we're in absorb mode, apply sponge permutation to compress the cache.\n self.perform_duplex();\n self.squeeze_mode = true;\n\n // Pop one item off the top of the permutation and return it.\n self.state[0]\n }\n\n fn hash_internal(\n input: [Field; N],\n in_len: u32,\n is_variable_length: bool,\n ) -> Field {\n let two_pow_64 = 18446744073709551616;\n let iv: Field = (in_len as Field) * two_pow_64;\n let mut sponge = Poseidon2::new(iv);\n for i in 0..input.len() {\n if i < in_len {\n sponge.absorb(input[i]);\n }\n }\n\n // In the case where the hash preimage is variable-length, we append `1` to the end of the input, to distinguish\n // from fixed-length hashes. (the combination of this additional field element + the hash IV ensures\n // fixed-length and variable-length hashes do not collide)\n if is_variable_length {\n sponge.absorb(1);\n }\n sponge.squeeze()\n }\n}\n\npub struct Poseidon2Hasher {\n _state: [Field],\n}\n\nimpl Hasher for Poseidon2Hasher {\n fn finish(self) -> Field {\n let iv: Field = (self._state.len() as Field) * 18446744073709551616; // iv = (self._state.len() << 64)\n let mut sponge = Poseidon2::new(iv);\n for i in 0..self._state.len() {\n sponge.absorb(self._state[i]);\n }\n sponge.squeeze()\n }\n\n fn write(&mut self, input: Field) {\n self._state = self._state.push_back(input);\n }\n}\n\nimpl Default for Poseidon2Hasher {\n fn default() -> Self {\n Poseidon2Hasher { _state: &[] }\n }\n}\n","path":"std/hash/poseidon2.nr"},"51":{"source":"use crate::cmp::{Eq, Ord, Ordering};\nuse crate::default::Default;\nuse crate::hash::{Hash, Hasher};\n\npub struct Option {\n _is_some: bool,\n _value: T,\n}\n\nimpl Option {\n /// Constructs a None value\n pub fn none() -> Self {\n Self { _is_some: false, _value: crate::mem::zeroed() }\n }\n\n /// Constructs a Some wrapper around the given value\n pub fn some(_value: T) -> Self {\n Self { _is_some: true, _value }\n }\n\n /// True if this Option is None\n pub fn is_none(self) -> bool {\n !self._is_some\n }\n\n /// True if this Option is Some\n pub fn is_some(self) -> bool {\n self._is_some\n }\n\n /// Asserts `self.is_some()` and returns the wrapped value.\n pub fn unwrap(self) -> T {\n assert(self._is_some);\n self._value\n }\n\n /// Returns the inner value without asserting `self.is_some()`\n /// Note that if `self` is `None`, there is no guarantee what value will be returned,\n /// only that it will be of type `T`.\n pub fn unwrap_unchecked(self) -> T {\n self._value\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, returns the given default value.\n pub fn unwrap_or(self, default: T) -> T {\n if self._is_some {\n self._value\n } else {\n default\n }\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, calls the given function to return\n /// a default value.\n pub fn unwrap_or_else(self, default: fn[Env]() -> T) -> T {\n if self._is_some {\n self._value\n } else {\n default()\n }\n }\n\n /// Asserts `self.is_some()` with a provided custom message and returns the contained `Some` value\n pub fn expect(self, message: fmtstr) -> T {\n assert(self.is_some(), message);\n self._value\n }\n\n /// If self is `Some(x)`, this returns `Some(f(x))`. Otherwise, this returns `None`.\n pub fn map(self, f: fn[Env](T) -> U) -> Option {\n if self._is_some {\n Option::some(f(self._value))\n } else {\n Option::none()\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns the given default value.\n pub fn map_or(self, default: U, f: fn[Env](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns `default()`.\n pub fn map_or_else(self, default: fn[Env1]() -> U, f: fn[Env2](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default()\n }\n }\n\n /// Returns None if self is None. Otherwise, this returns `other`.\n pub fn and(self, other: Self) -> Self {\n if self.is_none() {\n Option::none()\n } else {\n other\n }\n }\n\n /// If self is None, this returns None. Otherwise, this calls the given function\n /// with the Some value contained within self, and returns the result of that call.\n ///\n /// In some languages this function is called `flat_map` or `bind`.\n pub fn and_then(self, f: fn[Env](T) -> Option) -> Option {\n if self._is_some {\n f(self._value)\n } else {\n Option::none()\n }\n }\n\n /// If self is Some, return self. Otherwise, return `other`.\n pub fn or(self, other: Self) -> Self {\n if self._is_some {\n self\n } else {\n other\n }\n }\n\n /// If self is Some, return self. Otherwise, return `default()`.\n pub fn or_else(self, default: fn[Env]() -> Self) -> Self {\n if self._is_some {\n self\n } else {\n default()\n }\n }\n\n // If only one of the two Options is Some, return that option.\n // Otherwise, if both options are Some or both are None, None is returned.\n pub fn xor(self, other: Self) -> Self {\n if self._is_some {\n if other._is_some {\n Option::none()\n } else {\n self\n }\n } else if other._is_some {\n other\n } else {\n Option::none()\n }\n }\n\n /// Returns `Some(x)` if self is `Some(x)` and `predicate(x)` is true.\n /// Otherwise, this returns `None`\n pub fn filter(self, predicate: fn[Env](T) -> bool) -> Self {\n if self._is_some {\n if predicate(self._value) {\n self\n } else {\n Option::none()\n }\n } else {\n Option::none()\n }\n }\n\n /// Flattens an Option> into a Option.\n /// This returns None if the outer Option is None. Otherwise, this returns the inner Option.\n pub fn flatten(option: Option>) -> Option {\n if option._is_some {\n option._value\n } else {\n Option::none()\n }\n }\n}\n\nimpl Default for Option {\n fn default() -> Self {\n Option::none()\n }\n}\n\nimpl Eq for Option\nwhere\n T: Eq,\n{\n fn eq(self, other: Self) -> bool {\n if self._is_some == other._is_some {\n if self._is_some {\n self._value == other._value\n } else {\n true\n }\n } else {\n false\n }\n }\n}\n\nimpl Hash for Option\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self._is_some.hash(state);\n if self._is_some {\n self._value.hash(state);\n }\n }\n}\n\n// For this impl we're declaring Option::none < Option::some\nimpl Ord for Option\nwhere\n T: Ord,\n{\n fn cmp(self, other: Self) -> Ordering {\n if self._is_some {\n if other._is_some {\n self._value.cmp(other._value)\n } else {\n Ordering::greater()\n }\n } else if other._is_some {\n Ordering::less()\n } else {\n Ordering::equal()\n }\n }\n}\n","path":"std/option.nr"},"52":{"source":"pub fn panic(message: fmtstr) -> U {\n assert(false, message);\n crate::mem::zeroed()\n}\n","path":"std/panic.nr"},"62":{"source":"use dep::aztec::macros::aztec;\n\n#[aztec]\ncontract SimpleLogging {\n use dep::aztec::prelude::{Map, PublicMutable};\n use dep::aztec::{\n macros::{storage::storage, functions::{public, initializer, internal}},\n };\n #[storage]\n struct Storage {\n counters: Map, Context>,\n }\n\n #[public]\n #[initializer]\n fn constructor() {\n }\n\n #[public]\n #[internal]\n fn add_to_counter_public(counter_id: Field) {\n let new_counter_value = storage.counters.at(counter_id).read() + 1;\n storage.counters.at(counter_id).write(new_counter_value);\n }\n\n #[public]\n fn increase_counter_public(counter_id: Field) {\n context.emit_public_log(/*message=*/\"pub log\");\n SimpleLogging::at(context.this_address()).add_to_counter_public(counter_id);\n }\n unconstrained fn get_counter_value(counter_id: Field) -> pub Field {\n storage.counters.at(counter_id).read()\n }\n}\n","path":"/home/filip/c/chicmoz/services/event-cannon/src/contract-projects/SimpleLogging/src/main.nr"},"71":{"source":"use crate::context::gas::GasOpts;\nuse crate::hash::{\n compute_l1_to_l2_message_hash, compute_l1_to_l2_message_nullifier, compute_secret_hash,\n};\nuse dep::protocol_types::abis::function_selector::FunctionSelector;\nuse dep::protocol_types::address::{AztecAddress, EthAddress};\nuse dep::protocol_types::constants::MAX_FIELD_VALUE;\nuse dep::protocol_types::traits::{Empty, Packable, Serialize};\n\npub struct PublicContext {\n pub args_hash: Option,\n pub compute_args_hash: fn() -> Field,\n}\n\nimpl PublicContext {\n pub fn new(compute_args_hash: fn() -> Field) -> Self {\n PublicContext { args_hash: Option::none(), compute_args_hash }\n }\n\n pub fn emit_public_log(_self: &mut Self, log: T)\n where\n T: Serialize,\n {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { emit_public_log(Serialize::serialize(log).as_slice()) };\n }\n\n pub fn note_hash_exists(_self: Self, note_hash: Field, leaf_index: Field) -> bool {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { note_hash_exists(note_hash, leaf_index) } == 1\n }\n\n pub fn l1_to_l2_msg_exists(_self: Self, msg_hash: Field, msg_leaf_index: Field) -> bool {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { l1_to_l2_msg_exists(msg_hash, msg_leaf_index) } == 1\n }\n\n pub fn nullifier_exists(_self: Self, unsiloed_nullifier: Field, address: AztecAddress) -> bool {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { nullifier_exists(unsiloed_nullifier, address.to_field()) } == 1\n }\n\n pub fn consume_l1_to_l2_message(\n &mut self,\n content: Field,\n secret: Field,\n sender: EthAddress,\n leaf_index: Field,\n ) {\n let secret_hash = compute_secret_hash(secret);\n let message_hash = compute_l1_to_l2_message_hash(\n sender,\n self.chain_id(),\n /*recipient=*/\n self.this_address(),\n self.version(),\n content,\n secret_hash,\n leaf_index,\n );\n let nullifier = compute_l1_to_l2_message_nullifier(message_hash, secret);\n\n assert(\n !self.nullifier_exists(nullifier, self.this_address()),\n \"L1-to-L2 message is already nullified\",\n );\n assert(\n self.l1_to_l2_msg_exists(message_hash, leaf_index),\n \"Tried to consume nonexistent L1-to-L2 message\",\n );\n\n self.push_nullifier(nullifier);\n }\n\n pub fn message_portal(_self: &mut Self, recipient: EthAddress, content: Field) {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { send_l2_to_l1_msg(recipient, content) };\n }\n\n pub unconstrained fn call_public_function(\n _self: &mut Self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field],\n gas_opts: GasOpts,\n ) -> [Field] {\n let args = args.push_front(function_selector.to_field());\n let success = call(gas_for_call(gas_opts), contract_address, args);\n\n let result_data = returndata_copy(0, returndata_size());\n if !success {\n // Rethrow the revert data.\n avm_revert(result_data);\n }\n result_data\n }\n\n pub unconstrained fn static_call_public_function(\n _self: &mut Self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field],\n gas_opts: GasOpts,\n ) -> [Field] {\n let args = args.push_front(function_selector.to_field());\n let success = call_static(gas_for_call(gas_opts), contract_address, args);\n\n let result_data = returndata_copy(0, returndata_size());\n if !success {\n // Rethrow the revert data.\n avm_revert(result_data);\n }\n result_data\n }\n\n pub fn push_note_hash(_self: &mut Self, note_hash: Field) {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { emit_note_hash(note_hash) };\n }\n pub fn push_nullifier(_self: &mut Self, nullifier: Field) {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { emit_nullifier(nullifier) };\n }\n\n pub fn this_address(_self: Self) -> AztecAddress {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n address()\n }\n }\n pub fn msg_sender(_self: Self) -> AztecAddress {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n sender()\n }\n }\n pub fn selector(_self: Self) -> FunctionSelector {\n // The selector is the first element of the calldata when calling a public function through dispatch.\n /// Safety: AVM opcodes are constrained by the AVM itself\n let raw_selector: [Field; 1] = unsafe { calldata_copy(0, 1) };\n FunctionSelector::from_field(raw_selector[0])\n }\n pub fn get_args_hash(mut self) -> Field {\n if !self.args_hash.is_some() {\n self.args_hash = Option::some((self.compute_args_hash)());\n }\n\n self.args_hash.unwrap_unchecked()\n }\n pub fn transaction_fee(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n transaction_fee()\n }\n }\n\n pub fn chain_id(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n chain_id()\n }\n }\n pub fn version(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n version()\n }\n }\n pub fn block_number(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n block_number()\n }\n }\n pub fn timestamp(_self: Self) -> u64 {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n timestamp()\n }\n }\n pub fn fee_per_l2_gas(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n fee_per_l2_gas()\n }\n }\n pub fn fee_per_da_gas(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n fee_per_da_gas()\n }\n }\n\n pub fn l2_gas_left(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n l2_gas_left()\n }\n }\n pub fn da_gas_left(_self: Self) -> Field {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n da_gas_left()\n }\n }\n pub fn is_static_call(_self: Self) -> bool {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { is_static_call() } == 1\n }\n\n pub fn raw_storage_read(_self: Self, storage_slot: Field) -> [Field; N] {\n let mut out = [0; N];\n for i in 0..N {\n /// Safety: AVM opcodes are constrained by the AVM itself\n out[i] = unsafe { storage_read(storage_slot + i as Field) };\n }\n out\n }\n\n pub fn storage_read(self, storage_slot: Field) -> T\n where\n T: Packable,\n {\n T::unpack(self.raw_storage_read(storage_slot))\n }\n\n pub fn raw_storage_write(_self: Self, storage_slot: Field, values: [Field; N]) {\n for i in 0..N {\n /// Safety: AVM opcodes are constrained by the AVM itself\n unsafe { storage_write(storage_slot + i as Field, values[i]) };\n }\n }\n\n pub fn storage_write(self, storage_slot: Field, value: T)\n where\n T: Packable,\n {\n self.raw_storage_write(storage_slot, value.pack());\n }\n}\n\n// Helper functions\nfn gas_for_call(user_gas: GasOpts) -> [Field; 2] {\n // It's ok to use the max possible gas here, because the gas will be\n // capped by the gas left in the (STATIC)CALL instruction.\n [user_gas.l2_gas.unwrap_or(MAX_FIELD_VALUE), user_gas.da_gas.unwrap_or(MAX_FIELD_VALUE)]\n}\n\n// Unconstrained opcode wrappers (do not use directly).\nunconstrained fn address() -> AztecAddress {\n address_opcode()\n}\nunconstrained fn sender() -> AztecAddress {\n sender_opcode()\n}\nunconstrained fn transaction_fee() -> Field {\n transaction_fee_opcode()\n}\nunconstrained fn chain_id() -> Field {\n chain_id_opcode()\n}\nunconstrained fn version() -> Field {\n version_opcode()\n}\nunconstrained fn block_number() -> Field {\n block_number_opcode()\n}\nunconstrained fn timestamp() -> u64 {\n timestamp_opcode()\n}\nunconstrained fn fee_per_l2_gas() -> Field {\n fee_per_l2_gas_opcode()\n}\nunconstrained fn fee_per_da_gas() -> Field {\n fee_per_da_gas_opcode()\n}\nunconstrained fn l2_gas_left() -> Field {\n l2_gas_left_opcode()\n}\nunconstrained fn da_gas_left() -> Field {\n da_gas_left_opcode()\n}\nunconstrained fn is_static_call() -> Field {\n is_static_call_opcode()\n}\nunconstrained fn note_hash_exists(note_hash: Field, leaf_index: Field) -> u1 {\n note_hash_exists_opcode(note_hash, leaf_index)\n}\nunconstrained fn emit_note_hash(note_hash: Field) {\n emit_note_hash_opcode(note_hash)\n}\nunconstrained fn nullifier_exists(nullifier: Field, address: Field) -> u1 {\n nullifier_exists_opcode(nullifier, address)\n}\nunconstrained fn emit_nullifier(nullifier: Field) {\n emit_nullifier_opcode(nullifier)\n}\nunconstrained fn emit_public_log(message: [Field]) {\n emit_public_log_opcode(message)\n}\nunconstrained fn l1_to_l2_msg_exists(msg_hash: Field, msg_leaf_index: Field) -> u1 {\n l1_to_l2_msg_exists_opcode(msg_hash, msg_leaf_index)\n}\nunconstrained fn send_l2_to_l1_msg(recipient: EthAddress, content: Field) {\n send_l2_to_l1_msg_opcode(recipient, content)\n}\nunconstrained fn call(gas: [Field; 2], address: AztecAddress, args: [Field]) -> bool {\n call_opcode(gas, address, args)\n}\nunconstrained fn call_static(gas: [Field; 2], address: AztecAddress, args: [Field]) -> bool {\n call_static_opcode(gas, address, args)\n}\n\npub unconstrained fn calldata_copy(cdoffset: u32, copy_size: u32) -> [Field; N] {\n calldata_copy_opcode(cdoffset, copy_size)\n}\n\nunconstrained fn returndata_size() -> u32 {\n returndata_size_opcode()\n}\n\nunconstrained fn returndata_copy(rdoffset: u32, copy_size: u32) -> [Field] {\n returndata_copy_opcode(rdoffset, copy_size)\n}\n\npub unconstrained fn avm_return(returndata: [Field]) {\n return_opcode(returndata)\n}\n\n// This opcode reverts using the exact data given. In general it should only be used\n// to do rethrows, where the revert data is the same as the original revert data.\n// For normal reverts, use Noir's `assert` which, on top of reverting, will also add\n// an error selector to the revert data.\nunconstrained fn avm_revert(revertdata: [Field]) {\n revert_opcode(revertdata)\n}\n\nunconstrained fn storage_read(storage_slot: Field) -> Field {\n storage_read_opcode(storage_slot)\n}\n\nunconstrained fn storage_write(storage_slot: Field, value: Field) {\n storage_write_opcode(storage_slot, value);\n}\n\nimpl Empty for PublicContext {\n fn empty() -> Self {\n PublicContext::new(|| 0)\n }\n}\n\n// AVM oracles (opcodes) follow, do not use directly.\n#[oracle(avmOpcodeAddress)]\nunconstrained fn address_opcode() -> AztecAddress {}\n\n#[oracle(avmOpcodeSender)]\nunconstrained fn sender_opcode() -> AztecAddress {}\n\n#[oracle(avmOpcodeTransactionFee)]\nunconstrained fn transaction_fee_opcode() -> Field {}\n\n#[oracle(avmOpcodeChainId)]\nunconstrained fn chain_id_opcode() -> Field {}\n\n#[oracle(avmOpcodeVersion)]\nunconstrained fn version_opcode() -> Field {}\n\n#[oracle(avmOpcodeBlockNumber)]\nunconstrained fn block_number_opcode() -> Field {}\n\n#[oracle(avmOpcodeTimestamp)]\nunconstrained fn timestamp_opcode() -> u64 {}\n\n#[oracle(avmOpcodeFeePerL2Gas)]\nunconstrained fn fee_per_l2_gas_opcode() -> Field {}\n\n#[oracle(avmOpcodeFeePerDaGas)]\nunconstrained fn fee_per_da_gas_opcode() -> Field {}\n\n#[oracle(avmOpcodeL2GasLeft)]\nunconstrained fn l2_gas_left_opcode() -> Field {}\n\n#[oracle(avmOpcodeDaGasLeft)]\nunconstrained fn da_gas_left_opcode() -> Field {}\n\n#[oracle(avmOpcodeIsStaticCall)]\nunconstrained fn is_static_call_opcode() -> Field {}\n\n#[oracle(avmOpcodeNoteHashExists)]\nunconstrained fn note_hash_exists_opcode(note_hash: Field, leaf_index: Field) -> u1 {}\n\n#[oracle(avmOpcodeEmitNoteHash)]\nunconstrained fn emit_note_hash_opcode(note_hash: Field) {}\n\n#[oracle(avmOpcodeNullifierExists)]\nunconstrained fn nullifier_exists_opcode(nullifier: Field, address: Field) -> u1 {}\n\n#[oracle(avmOpcodeEmitNullifier)]\nunconstrained fn emit_nullifier_opcode(nullifier: Field) {}\n\n// TODO(#11124): rename unencrypted to public in avm\n#[oracle(avmOpcodeEmitUnencryptedLog)]\nunconstrained fn emit_public_log_opcode(message: [Field]) {}\n\n#[oracle(avmOpcodeL1ToL2MsgExists)]\nunconstrained fn l1_to_l2_msg_exists_opcode(msg_hash: Field, msg_leaf_index: Field) -> u1 {}\n\n#[oracle(avmOpcodeSendL2ToL1Msg)]\nunconstrained fn send_l2_to_l1_msg_opcode(recipient: EthAddress, content: Field) {}\n\n#[oracle(avmOpcodeCalldataCopy)]\nunconstrained fn calldata_copy_opcode(cdoffset: u32, copy_size: u32) -> [Field; N] {}\n\n#[oracle(avmOpcodeReturndataSize)]\nunconstrained fn returndata_size_opcode() -> u32 {}\n\n#[oracle(avmOpcodeReturndataCopy)]\nunconstrained fn returndata_copy_opcode(rdoffset: u32, copy_size: u32) -> [Field] {}\n\n#[oracle(avmOpcodeReturn)]\nunconstrained fn return_opcode(returndata: [Field]) {}\n\n// This opcode reverts using the exact data given. In general it should only be used\n// to do rethrows, where the revert data is the same as the original revert data.\n// For normal reverts, use Noir's `assert` which, on top of reverting, will also add\n// an error selector to the revert data.\n#[oracle(avmOpcodeRevert)]\nunconstrained fn revert_opcode(revertdata: [Field]) {}\n\n#[oracle(avmOpcodeCall)]\nunconstrained fn call_opcode(\n gas: [Field; 2], // gas allocation: [l2_gas, da_gas]\n address: AztecAddress,\n args: [Field],\n) -> bool {}\n\n#[oracle(avmOpcodeStaticCall)]\nunconstrained fn call_static_opcode(\n gas: [Field; 2], // gas allocation: [l2_gas, da_gas]\n address: AztecAddress,\n args: [Field],\n) -> bool {}\n\n#[oracle(avmOpcodeStorageRead)]\nunconstrained fn storage_read_opcode(storage_slot: Field) -> Field {}\n\n#[oracle(avmOpcodeStorageWrite)]\nunconstrained fn storage_write_opcode(storage_slot: Field, value: Field) {}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/aztec-nr/aztec/src/context/public_context.nr"},"73":{"source":"use crate::oracle::{\n execution::{get_block_number, get_chain_id, get_contract_address, get_version},\n storage::storage_read,\n};\nuse dep::protocol_types::{address::AztecAddress, traits::Packable};\n\npub struct UnconstrainedContext {\n block_number: u32,\n contract_address: AztecAddress,\n version: Field,\n chain_id: Field,\n}\n\nimpl UnconstrainedContext {\n pub unconstrained fn new() -> Self {\n // We could call these oracles on the getters instead of at creation, which makes sense given that they might\n // not even be accessed. However any performance gains are minimal, and we'd rather fail early if a user\n // incorrectly attempts to create an UnconstrainedContext in an environment in which these oracles are not\n // available.\n let block_number = get_block_number();\n let contract_address = get_contract_address();\n let chain_id = get_chain_id();\n let version = get_version();\n Self { block_number, contract_address, version, chain_id }\n }\n\n pub unconstrained fn at(contract_address: AztecAddress) -> Self {\n let block_number = get_block_number();\n let chain_id = get_chain_id();\n let version = get_version();\n Self { block_number, contract_address, version, chain_id }\n }\n\n pub unconstrained fn at_historical(contract_address: AztecAddress, block_number: u32) -> Self {\n let chain_id = get_chain_id();\n let version = get_version();\n Self { block_number, contract_address, version, chain_id }\n }\n\n pub fn block_number(self) -> u32 {\n self.block_number\n }\n\n pub fn this_address(self) -> AztecAddress {\n self.contract_address\n }\n\n pub fn version(self) -> Field {\n self.version\n }\n\n pub fn chain_id(self) -> Field {\n self.chain_id\n }\n\n pub unconstrained fn raw_storage_read(\n self: Self,\n storage_slot: Field,\n ) -> [Field; N] {\n storage_read(self.this_address(), storage_slot, self.block_number())\n }\n\n pub unconstrained fn storage_read(self, storage_slot: Field) -> T\n where\n T: Packable,\n {\n T::unpack(self.raw_storage_read(storage_slot))\n }\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/aztec-nr/aztec/src/context/unconstrained_context.nr"},"99":{"source":"use dep::protocol_types::{\n abis::function_selector::FunctionSelector, address::AztecAddress,\n constants::GENERATOR_INDEX__CONSTRUCTOR, hash::poseidon2_hash_with_separator,\n};\n\nuse crate::{\n context::{PrivateContext, PublicContext},\n oracle::get_contract_instance::{\n get_contract_instance, get_contract_instance_deployer_avm,\n get_contract_instance_initialization_hash_avm,\n },\n};\n\npub fn mark_as_initialized_public(context: &mut PublicContext) {\n let init_nullifier =\n compute_unsiloed_contract_initialization_nullifier((*context).this_address());\n context.push_nullifier(init_nullifier);\n}\n\npub fn mark_as_initialized_private(context: &mut PrivateContext) {\n let init_nullifier =\n compute_unsiloed_contract_initialization_nullifier((*context).this_address());\n context.push_nullifier(init_nullifier);\n}\n\npub fn assert_is_initialized_public(context: &mut PublicContext) {\n let init_nullifier = compute_unsiloed_contract_initialization_nullifier(context.this_address());\n assert(context.nullifier_exists(init_nullifier, context.this_address()), \"Not initialized\");\n}\n\npub fn assert_is_initialized_private(context: &mut PrivateContext) {\n let init_nullifier = compute_unsiloed_contract_initialization_nullifier(context.this_address());\n context.push_nullifier_read_request(init_nullifier);\n}\n\nfn compute_unsiloed_contract_initialization_nullifier(address: AztecAddress) -> Field {\n address.to_field()\n}\n\npub fn assert_initialization_matches_address_preimage_public(context: PublicContext) {\n let address = context.this_address();\n let deployer = get_contract_instance_deployer_avm(address).unwrap();\n let initialization_hash = get_contract_instance_initialization_hash_avm(address).unwrap();\n let expected_init = compute_initialization_hash(context.selector(), context.get_args_hash());\n assert(initialization_hash == expected_init, \"Initialization hash does not match\");\n assert(\n (deployer.is_zero()) | (deployer == context.msg_sender()),\n \"Initializer address is not the contract deployer\",\n );\n}\n\npub fn assert_initialization_matches_address_preimage_private(context: PrivateContext) {\n let address = context.this_address();\n let instance = get_contract_instance(address);\n let expected_init = compute_initialization_hash(context.selector(), context.get_args_hash());\n assert(instance.initialization_hash == expected_init, \"Initialization hash does not match\");\n assert(\n (instance.deployer.is_zero()) | (instance.deployer == context.msg_sender()),\n \"Initializer address is not the contract deployer\",\n );\n}\n\n/// This function is not only used in macros but it's also used by external people to check that an instance has been\n/// initialized with the correct constructor arguments. Don't hide this unless you implement factory functionality.\npub fn compute_initialization_hash(\n init_selector: FunctionSelector,\n init_args_hash: Field,\n) -> Field {\n poseidon2_hash_with_separator(\n [init_selector.to_field(), init_args_hash],\n GENERATOR_INDEX__CONSTRUCTOR,\n )\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/aztec-nr/aztec/src/macros/functions/initialization_utils.nr"},"123":{"source":"use dep::protocol_types::address::AztecAddress;\n\n#[oracle(getContractAddress)]\nunconstrained fn get_contract_address_oracle() -> AztecAddress {}\n\n#[oracle(getBlockNumber)]\nunconstrained fn get_block_number_oracle() -> u32 {}\n\n#[oracle(getChainId)]\nunconstrained fn get_chain_id_oracle() -> Field {}\n\n#[oracle(getVersion)]\nunconstrained fn get_version_oracle() -> Field {}\n\npub unconstrained fn get_contract_address() -> AztecAddress {\n get_contract_address_oracle()\n}\n\npub unconstrained fn get_block_number() -> u32 {\n get_block_number_oracle()\n}\n\npub unconstrained fn get_chain_id() -> Field {\n get_chain_id_oracle()\n}\n\npub unconstrained fn get_version() -> Field {\n get_version_oracle()\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/aztec-nr/aztec/src/oracle/execution.nr"},"125":{"source":"use dep::protocol_types::{\n address::AztecAddress, constants::CONTRACT_INSTANCE_LENGTH, contract_class_id::ContractClassId,\n contract_instance::ContractInstance,\n};\n\n// NOTE: this is for use in private only\n#[oracle(getContractInstance)]\nunconstrained fn get_contract_instance_oracle(\n _address: AztecAddress,\n) -> [Field; CONTRACT_INSTANCE_LENGTH] {}\n\n// NOTE: this is for use in private only\nunconstrained fn get_contract_instance_internal(\n address: AztecAddress,\n) -> [Field; CONTRACT_INSTANCE_LENGTH] {\n get_contract_instance_oracle(address)\n}\n\n// NOTE: this is for use in private only\npub fn get_contract_instance(address: AztecAddress) -> ContractInstance {\n /// Safety: The to_address function combines all values in the instance object to produce an address,\n /// so by checking that we get the expected address we validate the entire struct.\n let instance =\n unsafe { ContractInstance::deserialize(get_contract_instance_internal(address)) };\n assert_eq(instance.to_address(), address);\n\n instance\n}\n\n// These oracles each return a ContractInstance member\n// plus a boolean indicating whether the instance was found.\n#[oracle(avmOpcodeGetContractInstanceDeployer)]\nunconstrained fn get_contract_instance_deployer_oracle_avm(\n _address: AztecAddress,\n) -> (Field, bool) {}\n#[oracle(avmOpcodeGetContractInstanceClassId)]\nunconstrained fn get_contract_instance_class_id_oracle_avm(\n _address: AztecAddress,\n) -> (Field, bool) {}\n#[oracle(avmOpcodeGetContractInstanceInitializationHash)]\nunconstrained fn get_contract_instance_initialization_hash_oracle_avm(\n _address: AztecAddress,\n) -> (Field, bool) {}\n\npub unconstrained fn get_contract_instance_deployer_internal_avm(\n address: AztecAddress,\n) -> (Field, bool) {\n get_contract_instance_deployer_oracle_avm(address)\n}\npub unconstrained fn get_contract_instance_class_id_internal_avm(\n address: AztecAddress,\n) -> (Field, bool) {\n get_contract_instance_class_id_oracle_avm(address)\n}\npub unconstrained fn get_contract_instance_initialization_hash_internal_avm(\n address: AztecAddress,\n) -> (Field, bool) {\n get_contract_instance_initialization_hash_oracle_avm(address)\n}\n\npub fn get_contract_instance_deployer_avm(address: AztecAddress) -> Option {\n /// Safety: AVM opcodes are constrained by the AVM itself\n let (member, exists) = unsafe { get_contract_instance_deployer_internal_avm(address) };\n if exists {\n Option::some(AztecAddress::from_field(member))\n } else {\n Option::none()\n }\n}\npub fn get_contract_instance_class_id_avm(address: AztecAddress) -> Option {\n /// Safety: AVM opcodes are constrained by the AVM itself\n let (member, exists) = unsafe { get_contract_instance_class_id_internal_avm(address) };\n if exists {\n Option::some(ContractClassId::from_field(member))\n } else {\n Option::none()\n }\n}\npub fn get_contract_instance_initialization_hash_avm(address: AztecAddress) -> Option {\n /// Safety: AVM opcodes are constrained by the AVM itself\n let (member, exists) =\n unsafe { get_contract_instance_initialization_hash_internal_avm(address) };\n if exists {\n Option::some(member)\n } else {\n Option::none()\n }\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/aztec-nr/aztec/src/oracle/get_contract_instance.nr"},"135":{"source":"use crate::{note::{note_header::NoteHeader, note_interface::NoteInterface}, utils::array};\n\nuse dep::protocol_types::{\n address::AztecAddress,\n indexed_tagging_secret::{INDEXED_TAGGING_SECRET_LENGTH, IndexedTaggingSecret},\n};\n\n/// Notifies the simulator that a note has been created, so that it can be returned in future read requests in the same\n/// transaction. This note should only be added to the non-volatile database if found in an actual block.\npub fn notify_created_note(\n storage_slot: Field,\n note_type_id: Field,\n serialized_note: [Field; N],\n note_hash: Field,\n counter: u32,\n) {\n /// Safety: This oracle call returns nothing: we only call it for its side effects. It is therefore always safe\n /// to call.\n unsafe {\n notify_created_note_oracle_wrapper(\n storage_slot,\n note_type_id,\n serialized_note,\n note_hash,\n counter,\n )\n };\n}\n\n/// Notifies the simulator that a note has been nullified, so that it is no longer returned in future read requests in\n/// the same transaction. This note should only be removed to the non-volatile database if its nullifier is found in an\n/// actual block.\npub fn notify_nullified_note(nullifier: Field, note_hash: Field, counter: u32) {\n /// Safety: This oracle call returns nothing: we only call it for its side effects. It is therefore always safe\n /// to call.\n unsafe { notify_nullified_note_oracle_wrapper(nullifier, note_hash, counter) };\n}\n\n/// Notifies the simulator that a non-note nullifier has been created, so that it can be used for note nonces.\npub fn notify_created_nullifier(nullifier: Field) {\n // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe to call.\n unsafe { notify_created_nullifier_oracle_wrapper(nullifier) };\n}\n\nunconstrained fn notify_created_note_oracle_wrapper(\n storage_slot: Field,\n note_type_id: Field,\n serialized_note: [Field; N],\n note_hash: Field,\n counter: u32,\n) {\n let _ = notify_created_note_oracle(\n storage_slot,\n note_type_id,\n serialized_note,\n note_hash,\n counter,\n );\n}\n\n#[oracle(notifyCreatedNote)]\nunconstrained fn notify_created_note_oracle(\n _storage_slot: Field,\n _note_type_id: Field,\n _serialized_note: [Field; N],\n _note_hash: Field,\n _counter: u32,\n) -> Field {}\n\nunconstrained fn notify_nullified_note_oracle_wrapper(\n nullifier: Field,\n note_hash: Field,\n counter: u32,\n) {\n let _ = notify_nullified_note_oracle(nullifier, note_hash, counter);\n}\n\n#[oracle(notifyNullifiedNote)]\nunconstrained fn notify_nullified_note_oracle(\n _nullifier: Field,\n _note_hash: Field,\n _counter: u32,\n) -> Field {}\n\nunconstrained fn notify_created_nullifier_oracle_wrapper(nullifier: Field) {\n let _ = notify_created_nullifier_oracle(nullifier);\n}\n\n#[oracle(notifyCreatedNullifier)]\nunconstrained fn notify_created_nullifier_oracle(_nullifier: Field) -> Field {}\n\n#[oracle(getNotes)]\nunconstrained fn get_notes_oracle(\n _storage_slot: Field,\n _num_selects: u8,\n _select_by_indexes: [u8; N],\n _select_by_offsets: [u8; N],\n _select_by_lengths: [u8; N],\n _select_values: [Field; N],\n _select_comparators: [u8; N],\n _sort_by_indexes: [u8; N],\n _sort_by_offsets: [u8; N],\n _sort_by_lengths: [u8; N],\n _sort_order: [u8; N],\n _limit: u32,\n _offset: u32,\n _status: u8,\n _return_size: u32,\n _placeholder_fields: [Field; S],\n) -> [Field; S] {}\n\nunconstrained fn get_notes_oracle_wrapper(\n storage_slot: Field,\n num_selects: u8,\n select_by_indexes: [u8; N],\n select_by_offsets: [u8; N],\n select_by_lengths: [u8; N],\n select_values: [Field; N],\n select_comparators: [u8; N],\n sort_by_indexes: [u8; N],\n sort_by_offsets: [u8; N],\n sort_by_lengths: [u8; N],\n sort_order: [u8; N],\n limit: u32,\n offset: u32,\n status: u8,\n mut placeholder_fields: [Field; S],\n) -> [Field; S] {\n let return_size = placeholder_fields.len() as u32;\n get_notes_oracle(\n storage_slot,\n num_selects,\n select_by_indexes,\n select_by_offsets,\n select_by_lengths,\n select_values,\n select_comparators,\n sort_by_indexes,\n sort_by_offsets,\n sort_by_lengths,\n sort_order,\n limit,\n offset,\n status,\n return_size,\n placeholder_fields,\n )\n}\n\npub unconstrained fn get_notes(\n storage_slot: Field,\n num_selects: u8,\n select_by_indexes: [u8; M],\n select_by_offsets: [u8; M],\n select_by_lengths: [u8; M],\n select_values: [Field; M],\n select_comparators: [u8; M],\n sort_by_indexes: [u8; M],\n sort_by_offsets: [u8; M],\n sort_by_lengths: [u8; M],\n sort_order: [u8; M],\n limit: u32,\n offset: u32,\n status: u8,\n mut placeholder_opt_notes: [Option; S], // TODO: Remove it and use `limit` to initialize the note array.\n placeholder_fields: [Field; NS], // TODO: Remove it and use `limit` to initialize the note array.\n _placeholder_note_length: [Field; N], // Turbofish hack? Compiler breaks calculating read_offset unless we add this parameter\n) -> [Option; S]\nwhere\n Note: NoteInterface,\n{\n sync_notes_oracle_wrapper();\n let fields = get_notes_oracle_wrapper(\n storage_slot,\n num_selects,\n select_by_indexes,\n select_by_offsets,\n select_by_lengths,\n select_values,\n select_comparators,\n sort_by_indexes,\n sort_by_offsets,\n sort_by_lengths,\n sort_order,\n limit,\n offset,\n status,\n placeholder_fields,\n );\n let num_notes = fields[0] as u32;\n let contract_address = AztecAddress::from_field(fields[1]);\n for i in 0..placeholder_opt_notes.len() {\n if i < num_notes {\n // lengths named as per typescript.\n let return_header_length: u32 = 2; // num_notes & contract_address.\n let extra_preimage_length: u32 = 2; // nonce & note_hash_counter.\n let read_offset: u32 = return_header_length + i * (N + extra_preimage_length);\n\n let nonce = fields[read_offset];\n let note_hash_counter = fields[read_offset + 1] as u32;\n let note_content = array::subarray(fields, read_offset + 2);\n\n let mut note = Note::deserialize_content(note_content);\n note.set_header(NoteHeader { contract_address, nonce, storage_slot, note_hash_counter });\n\n placeholder_opt_notes[i] = Option::some(note);\n };\n }\n placeholder_opt_notes\n}\n\n/// Returns true if the nullifier exists. Note that a `true` value can be constrained by proving existence of the\n/// nullifier, but a `false` value should not be relied upon since other transactions may emit this nullifier before the\n/// current transaction is included in a block. While this might seem of little use at first, certain design patterns\n/// benefit from this abstraction (see e.g. `PrivateMutable`).\npub unconstrained fn check_nullifier_exists(inner_nullifier: Field) -> bool {\n check_nullifier_exists_oracle(inner_nullifier) == 1\n}\n\n#[oracle(checkNullifierExists)]\nunconstrained fn check_nullifier_exists_oracle(_inner_nullifier: Field) -> Field {}\n\n/// Same as `get_indexed_tagging_secret_as_sender`, except it returns the derived tag, ready to be included in a log.\npub unconstrained fn get_app_tag_as_sender(sender: AztecAddress, recipient: AztecAddress) -> Field {\n get_indexed_tagging_secret_as_sender(sender, recipient).compute_tag(recipient)\n}\n\n/// Returns the tagging secret for a given sender and recipient pair, siloed for the current contract address.\n/// Includes the last known index used to send a note tagged with this secret.\n/// For this to work, PXE must know the ivsk_m of the sender.\n/// For the recipient's side, only the address is needed.\npub unconstrained fn get_indexed_tagging_secret_as_sender(\n sender: AztecAddress,\n recipient: AztecAddress,\n) -> IndexedTaggingSecret {\n let result = get_indexed_tagging_secret_as_sender_oracle(sender, recipient);\n IndexedTaggingSecret::deserialize(result)\n}\n\n#[oracle(getIndexedTaggingSecretAsSender)]\nunconstrained fn get_indexed_tagging_secret_as_sender_oracle(\n _sender: AztecAddress,\n _recipient: AztecAddress,\n) -> [Field; INDEXED_TAGGING_SECRET_LENGTH] {}\n\n/// Notifies the simulator that a tag has been used in a note, and to therefore increment the associated index so that\n/// future notes get a different tag and can be discovered by the recipient.\n/// This change should only be persisted in a non-volatile database if the tagged log is found in an actual block -\n/// otherwise e.g. a reverting transaction can cause the sender to accidentally skip indices and later produce notes\n/// that are not found by the recipient.\npub fn increment_app_tagging_secret_index_as_sender(sender: AztecAddress, recipient: AztecAddress) {\n /// Safety: This oracle call returns nothing: we only call it for its side effects. It is therefore always safe\n /// to call.\n unsafe {\n increment_app_tagging_secret_index_as_sender_wrapper(sender, recipient);\n }\n}\n\nunconstrained fn increment_app_tagging_secret_index_as_sender_wrapper(\n sender: AztecAddress,\n recipient: AztecAddress,\n) {\n increment_app_tagging_secret_index_as_sender_oracle(sender, recipient);\n}\n\n#[oracle(incrementAppTaggingSecretIndexAsSender)]\nunconstrained fn increment_app_tagging_secret_index_as_sender_oracle(\n _sender: AztecAddress,\n _recipient: AztecAddress,\n) {}\n\n/// Finds new notes that may have been sent to all registered accounts in PXE in the current contract and makes them available\n/// for later querying via the `get_notes` oracle.\npub fn sync_notes() {\n /// Safety: This oracle call returns nothing: we only call it for its side effects. It is therefore always safe\n /// to call.\n unsafe {\n sync_notes_oracle_wrapper();\n }\n}\n\nunconstrained fn sync_notes_oracle_wrapper() {\n sync_notes_oracle();\n}\n\n#[oracle(syncNotes)]\nunconstrained fn sync_notes_oracle() {}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/aztec-nr/aztec/src/oracle/notes.nr"},"138":{"source":"use dep::protocol_types::{address::AztecAddress, traits::Packable};\n\n#[oracle(storageRead)]\nunconstrained fn storage_read_oracle(\n address: Field,\n storage_slot: Field,\n block_number: Field,\n length: Field,\n) -> [Field; N] {}\n\npub unconstrained fn raw_storage_read(\n address: AztecAddress,\n storage_slot: Field,\n block_number: u32,\n) -> [Field; N] {\n storage_read_oracle(\n address.to_field(),\n storage_slot,\n block_number as Field,\n N as Field,\n )\n}\n\npub unconstrained fn storage_read(\n address: AztecAddress,\n storage_slot: Field,\n block_number: u32,\n) -> T\nwhere\n T: Packable,\n{\n T::unpack(raw_storage_read(address, storage_slot, block_number))\n}\n\nmod tests {\n use crate::oracle::storage::{raw_storage_read, storage_read};\n use dep::protocol_types::{address::AztecAddress, traits::{FromField, Packable}};\n\n use crate::test::mocks::mock_struct::MockStruct;\n use std::test::OracleMock;\n\n global address: AztecAddress = AztecAddress::from_field(29);\n global slot: Field = 7;\n global block_number: u32 = 17;\n\n #[test]\n unconstrained fn test_raw_storage_read() {\n let written = MockStruct { a: 13, b: 42 };\n\n let _ = OracleMock::mock(\"storageRead\").returns(written.pack());\n\n let read: [Field; 2] = raw_storage_read(address, slot, block_number);\n assert_eq(read[0], 13);\n assert_eq(read[1], 42);\n }\n\n #[test]\n unconstrained fn test_storage_read() {\n let written = MockStruct { a: 13, b: 42 };\n\n let _ = OracleMock::mock(\"storageRead\").returns(written.pack());\n\n let read: MockStruct = storage_read(address, slot, block_number);\n assert_eq(read.a, 13);\n assert_eq(read.b, 42);\n }\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/aztec-nr/aztec/src/oracle/storage.nr"},"141":{"source":"use crate::state_vars::storage::Storage;\nuse dep::protocol_types::{storage::map::derive_storage_slot_in_map, traits::{Packable, ToField}};\n\n// docs:start:map\npub struct Map {\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V,\n}\n// docs:end:map\n\nimpl Storage for Map\nwhere\n T: Packable,\n{\n fn get_storage_slot(self) -> Field {\n self.storage_slot\n }\n}\n\nimpl Map {\n // docs:start:new\n pub fn new(\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V,\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Map { context, storage_slot, state_var_constructor }\n }\n // docs:end:new\n\n // docs:start:at\n pub fn at(self, key: K) -> V\n where\n K: ToField,\n {\n // TODO(#1204): use a generator index for the storage slot\n let derived_storage_slot = derive_storage_slot_in_map(self.storage_slot, key);\n\n let state_var_constructor = self.state_var_constructor;\n state_var_constructor(self.context, derived_storage_slot)\n }\n // docs:end:at\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/aztec-nr/aztec/src/state_vars/map.nr"},"149":{"source":"use crate::context::{PublicContext, UnconstrainedContext};\nuse crate::state_vars::storage::Storage;\nuse dep::protocol_types::traits::Packable;\n\n// docs:start:public_mutable_struct\npub struct PublicMutable {\n context: Context,\n storage_slot: Field,\n}\n// docs:end:public_mutable_struct\n\nimpl Storage for PublicMutable\nwhere\n T: Packable,\n{\n fn get_storage_slot(self) -> Field {\n self.storage_slot\n }\n}\n\nimpl PublicMutable {\n // docs:start:public_mutable_struct_new\n pub fn new(\n // Note: Passing the contexts to new(...) just to have an interface compatible with a Map.\n context: Context,\n storage_slot: Field,\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n PublicMutable { context, storage_slot }\n }\n // docs:end:public_mutable_struct_new\n}\n\nimpl PublicMutable\nwhere\n T: Packable,\n{\n // docs:start:public_mutable_struct_read\n pub fn read(self) -> T {\n self.context.storage_read(self.storage_slot)\n }\n // docs:end:public_mutable_struct_read\n\n // docs:start:public_mutable_struct_write\n pub fn write(self, value: T) {\n self.context.storage_write(self.storage_slot, value);\n }\n // docs:end:public_mutable_struct_write\n}\n\nimpl PublicMutable\nwhere\n T: Packable,\n{\n pub unconstrained fn read(self) -> T {\n self.context.storage_read(self.storage_slot)\n }\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr"},"192":{"source":"use crate::traits::{Deserialize, Empty, FromField, Serialize, ToField};\n\npub struct FunctionSelector {\n // 1st 4-bytes of abi-encoding of function.\n pub inner: u32,\n}\n\nimpl Eq for FunctionSelector {\n fn eq(self, function_selector: FunctionSelector) -> bool {\n function_selector.inner == self.inner\n }\n}\n\nimpl Serialize<1> for FunctionSelector {\n fn serialize(self: Self) -> [Field; 1] {\n [self.inner as Field]\n }\n}\n\nimpl Deserialize<1> for FunctionSelector {\n fn deserialize(fields: [Field; 1]) -> Self {\n Self { inner: fields[0] as u32 }\n }\n}\n\nimpl FromField for FunctionSelector {\n fn from_field(field: Field) -> Self {\n Self { inner: field as u32 }\n }\n}\n\nimpl ToField for FunctionSelector {\n fn to_field(self) -> Field {\n self.inner as Field\n }\n}\n\nimpl Empty for FunctionSelector {\n fn empty() -> Self {\n Self { inner: 0 as u32 }\n }\n}\n\nimpl FunctionSelector {\n pub fn from_u32(value: u32) -> Self {\n Self { inner: value }\n }\n\n pub fn from_signature(signature: str) -> Self {\n let bytes = signature.as_bytes();\n let hash = crate::hash::poseidon2_hash_bytes(bytes);\n\n // `hash` is automatically truncated to fit within 32 bits.\n FunctionSelector::from_field(hash)\n }\n\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n}\n\n#[test]\nfn test_is_valid_selector() {\n let selector = FunctionSelector::from_signature(\"IS_VALID()\");\n assert_eq(selector.to_field(), 0x73cdda47);\n}\n\n#[test]\nfn test_long_selector() {\n let selector =\n FunctionSelector::from_signature(\"foo_and_bar_and_baz_and_foo_bar_baz_and_bar_foo\");\n assert_eq(selector.to_field(), 0x7590a997);\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/noir-protocol-circuits/crates/types/src/abis/function_selector.nr"},"234":{"source":"use crate::{\n abis::function_selector::FunctionSelector,\n address::{\n partial_address::PartialAddress, salted_initialization_hash::SaltedInitializationHash,\n },\n constants::{\n AZTEC_ADDRESS_LENGTH, FUNCTION_TREE_HEIGHT, GENERATOR_INDEX__CONTRACT_ADDRESS_V1,\n MAX_FIELD_VALUE,\n },\n contract_class_id::ContractClassId,\n hash::{poseidon2_hash_with_separator, private_functions_root_from_siblings},\n merkle_tree::membership::MembershipWitness,\n public_keys::{IvpkM, NpkM, OvpkM, PublicKeys, ToPoint, TpkM},\n traits::{Deserialize, Empty, FromField, Packable, Serialize, ToField},\n};\n\n// We do below because `use crate::point::Point;` does not work\nuse dep::std::embedded_curve_ops::EmbeddedCurvePoint as Point;\n\nuse crate::public_keys::AddressPoint;\nuse ec::{pow, sqrt};\nuse std::{\n embedded_curve_ops::{EmbeddedCurveScalar, fixed_base_scalar_mul as derive_public_key},\n ops::Add,\n};\n\n// Aztec address\npub struct AztecAddress {\n pub inner: Field,\n}\n\nimpl Eq for AztecAddress {\n fn eq(self, other: Self) -> bool {\n self.to_field() == other.to_field()\n }\n}\n\nimpl Empty for AztecAddress {\n fn empty() -> Self {\n Self { inner: 0 }\n }\n}\n\nimpl ToField for AztecAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl FromField for AztecAddress {\n fn from_field(value: Field) -> AztecAddress {\n AztecAddress { inner: value }\n }\n}\n\nimpl Serialize for AztecAddress {\n fn serialize(self: Self) -> [Field; AZTEC_ADDRESS_LENGTH] {\n [self.to_field()]\n }\n}\n\nimpl Deserialize for AztecAddress {\n fn deserialize(fields: [Field; AZTEC_ADDRESS_LENGTH]) -> Self {\n FromField::from_field(fields[0])\n }\n}\n\n/// We implement the Packable trait for AztecAddress because it can be stored in contract's storage (and there\n/// the implementation of Packable is required).\nimpl Packable for AztecAddress {\n fn pack(self) -> [Field; AZTEC_ADDRESS_LENGTH] {\n self.serialize()\n }\n\n fn unpack(fields: [Field; AZTEC_ADDRESS_LENGTH]) -> Self {\n Self::deserialize(fields)\n }\n}\n\nimpl AztecAddress {\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n\n pub fn to_address_point(self) -> AddressPoint {\n // We compute the address point by taking our address, setting it to x, and then solving for y in the\n // equation which defines our bn curve:\n // y^2 = x^3 - 17; x = address\n let x = self.inner;\n let y_squared = pow(x, 3) - 17;\n\n // TODO (#8970): Handle cases where we cannot recover a point from an address\n let mut y = sqrt(y_squared);\n\n // If we get a negative y coordinate (any y where y > MAX_FIELD_VALUE / 2), we pin it to the\n // positive one (any value where y <= MAX_FIELD_VALUE / 2) by subtracting it from the Field modulus\n // note: The field modulus is MAX_FIELD_VALUE + 1\n if (!(y.lt(MAX_FIELD_VALUE / 2) | y.eq(MAX_FIELD_VALUE / 2))) {\n y = (MAX_FIELD_VALUE + 1) - y;\n }\n\n AddressPoint { inner: Point { x: self.inner, y, is_infinite: false } }\n }\n\n pub fn compute(public_keys: PublicKeys, partial_address: PartialAddress) -> AztecAddress {\n let public_keys_hash = public_keys.hash();\n\n let pre_address = poseidon2_hash_with_separator(\n [public_keys_hash.to_field(), partial_address.to_field()],\n GENERATOR_INDEX__CONTRACT_ADDRESS_V1,\n );\n\n let address_point = derive_public_key(EmbeddedCurveScalar::from_field(pre_address)).add(\n public_keys.ivpk_m.to_point(),\n );\n\n // Note that our address is only the x-coordinate of the full address_point. This is okay because when people want to encrypt something and send it to us\n // they can recover our full point using the x-coordinate (our address itself). To do this, they recompute the y-coordinate according to the equation y^2 = x^3 - 17.\n // When they do this, they may get a positive y-coordinate (a value that is less than or equal to MAX_FIELD_VALUE / 2) or\n // a negative y-coordinate (a value that is more than MAX_FIELD_VALUE), and we cannot dictate which one they get and hence the recovered point may sometimes be different than the one\n // our secrect can decrypt. Regardless though, they should and will always encrypt using point with the positive y-coordinate by convention.\n // This ensures that everyone encrypts to the same point given an arbitrary x-coordinate (address). This is allowed because even though our original point may not have a positive y-coordinate,\n // with our original secret, we will be able to derive the secret to the point with the flipped (and now positive) y-coordinate that everyone encrypts to.\n AztecAddress::from_field(address_point.x)\n }\n\n pub fn compute_from_private_function(\n function_selector: FunctionSelector,\n function_vk_hash: Field,\n function_leaf_membership_witness: MembershipWitness,\n contract_class_artifact_hash: Field,\n contract_class_public_bytecode_commitment: Field,\n salted_initialization_hash: SaltedInitializationHash,\n public_keys: PublicKeys,\n ) -> Self {\n let private_functions_root = private_functions_root_from_siblings(\n function_selector,\n function_vk_hash,\n function_leaf_membership_witness.leaf_index,\n function_leaf_membership_witness.sibling_path,\n );\n\n let contract_class_id = ContractClassId::compute(\n contract_class_artifact_hash,\n private_functions_root,\n contract_class_public_bytecode_commitment,\n );\n\n // Compute contract address using the preimage which includes the class_id.\n let partial_address = PartialAddress::compute_from_salted_initialization_hash(\n contract_class_id,\n salted_initialization_hash,\n );\n\n AztecAddress::compute(public_keys, partial_address)\n }\n\n pub fn is_zero(self) -> bool {\n self.inner == 0\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\n#[test]\nfn compute_address_from_partial_and_pub_keys() {\n let public_keys = PublicKeys {\n npk_m: NpkM {\n inner: Point {\n x: 0x22f7fcddfa3ce3e8f0cc8e82d7b94cdd740afa3e77f8e4a63ea78a239432dcab,\n y: 0x0471657de2b6216ade6c506d28fbc22ba8b8ed95c871ad9f3e3984e90d9723a7,\n is_infinite: false,\n },\n },\n ivpk_m: IvpkM {\n inner: Point {\n x: 0x111223493147f6785514b1c195bb37a2589f22a6596d30bb2bb145fdc9ca8f1e,\n y: 0x273bbffd678edce8fe30e0deafc4f66d58357c06fd4a820285294b9746c3be95,\n is_infinite: false,\n },\n },\n ovpk_m: OvpkM {\n inner: Point {\n x: 0x09115c96e962322ffed6522f57194627136b8d03ac7469109707f5e44190c484,\n y: 0x0c49773308a13d740a7f0d4f0e6163b02c5a408b6f965856b6a491002d073d5b,\n is_infinite: false,\n },\n },\n tpk_m: TpkM {\n inner: Point {\n x: 0x00d3d81beb009873eb7116327cf47c612d5758ef083d4fda78e9b63980b2a762,\n y: 0x2f567d22d2b02fe1f4ad42db9d58a36afd1983e7e2909d1cab61cafedad6193a,\n is_infinite: false,\n },\n },\n };\n\n let partial_address = PartialAddress::from_field(\n 0x0a7c585381b10f4666044266a02405bf6e01fa564c8517d4ad5823493abd31de,\n );\n\n let address = AztecAddress::compute(public_keys, partial_address);\n\n // The following value was generated by `derivation.test.ts`.\n // --> Run the test with AZTEC_GENERATE_TEST_DATA=1 flag to update test data.\n let expected_computed_address_from_partial_and_pubkeys =\n 0x24e4646f58b9fbe7d38e317db8d5636c423fbbdfbe119fc190fe9c64747e0c62;\n assert(address.to_field() == expected_computed_address_from_partial_and_pubkeys);\n}\n\n#[test]\nfn compute_preaddress_from_partial_and_pub_keys() {\n let pre_address = poseidon2_hash_with_separator([1, 2], GENERATOR_INDEX__CONTRACT_ADDRESS_V1);\n let expected_computed_preaddress_from_partial_and_pubkey =\n 0x23ce9be3fa3c846b0f9245cc796902e731d04f086e8a42473bb29e405fc98075;\n assert(pre_address == expected_computed_preaddress_from_partial_and_pubkey);\n}\n\n#[test]\nfn from_field_to_field() {\n let address = AztecAddress { inner: 37 };\n assert_eq(FromField::from_field(address.to_field()), address);\n}\n\n#[test]\nfn serde() {\n let address = AztecAddress { inner: 37 };\n assert_eq(Deserialize::deserialize(address.serialize()), address);\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr"},"251":{"source":"use crate::{\n abis::{\n contract_class_function_leaf_preimage::ContractClassFunctionLeafPreimage,\n function_selector::FunctionSelector,\n log_hash::{LogHash, ScopedLogHash},\n note_hash::ScopedNoteHash,\n nullifier::ScopedNullifier,\n private_log::{PrivateLog, PrivateLogData},\n side_effect::{OrderedValue, scoped::Scoped},\n },\n address::{AztecAddress, EthAddress},\n constants::{\n FUNCTION_TREE_HEIGHT, GENERATOR_INDEX__NOTE_HASH_NONCE, GENERATOR_INDEX__OUTER_NULLIFIER,\n GENERATOR_INDEX__SILOED_NOTE_HASH, GENERATOR_INDEX__UNIQUE_NOTE_HASH,\n },\n merkle_tree::root::root_from_sibling_path,\n messaging::l2_to_l1_message::{L2ToL1Message, ScopedL2ToL1Message},\n poseidon2::Poseidon2Sponge,\n traits::{FromField, Hash, is_empty, ToField},\n utils::field::field_from_bytes_32_trunc,\n};\nuse super::{constants::TWO_POW_64, utils::{arrays::array_concat, field::field_from_bytes}};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = std::hash::sha256(bytes_to_hash);\n let hash_in_a_field = field_from_bytes_32_trunc(sha256_hashed);\n\n hash_in_a_field\n}\n\npub fn private_functions_root_from_siblings(\n selector: FunctionSelector,\n vk_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT],\n) -> Field {\n let function_leaf_preimage = ContractClassFunctionLeafPreimage { selector, vk_hash };\n let function_leaf = function_leaf_preimage.hash();\n root_from_sibling_path(\n function_leaf,\n function_leaf_index,\n function_leaf_sibling_path,\n )\n}\n\npub fn compute_note_hash_nonce(first_nullifier_in_tx: Field, note_index_in_tx: u32) -> Field {\n // Hashing the first nullifier with note index in tx is guaranteed to be unique (because all nullifiers are also\n // unique).\n poseidon2_hash_with_separator(\n [first_nullifier_in_tx, note_index_in_tx as Field],\n GENERATOR_INDEX__NOTE_HASH_NONCE,\n )\n}\n\npub fn compute_unique_note_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n let inputs = [nonce, siloed_note_hash];\n poseidon2_hash_with_separator(inputs, GENERATOR_INDEX__UNIQUE_NOTE_HASH)\n}\n\npub fn compute_siloed_note_hash(app: AztecAddress, note_hash: Field) -> Field {\n poseidon2_hash_with_separator(\n [app.to_field(), note_hash],\n GENERATOR_INDEX__SILOED_NOTE_HASH,\n )\n}\n\n/// Computes unique note hashes from siloed note hashes\npub fn compute_unique_siloed_note_hash(\n siloed_note_hash: Field,\n first_nullifier: Field,\n note_index_in_tx: u32,\n) -> Field {\n if siloed_note_hash == 0 {\n 0\n } else {\n let nonce = compute_note_hash_nonce(first_nullifier, note_index_in_tx);\n compute_unique_note_hash(nonce, siloed_note_hash)\n }\n}\n\n/// Siloing in the context of Aztec refers to the process of hashing a note hash with a contract address (this way\n/// the note hash is scoped to a specific contract). This is used to prevent intermingling of notes between contracts.\npub fn silo_note_hash(note_hash: ScopedNoteHash) -> Field {\n if note_hash.contract_address.is_zero() {\n 0\n } else {\n compute_siloed_note_hash(note_hash.contract_address, note_hash.value())\n }\n}\n\npub fn compute_siloed_nullifier(app: AztecAddress, nullifier: Field) -> Field {\n poseidon2_hash_with_separator(\n [app.to_field(), nullifier],\n GENERATOR_INDEX__OUTER_NULLIFIER,\n )\n}\n\npub fn silo_nullifier(nullifier: ScopedNullifier) -> Field {\n if nullifier.contract_address.is_zero() {\n nullifier.value() // Return value instead of 0 because the first nullifier's contract address is zero.\n } else {\n compute_siloed_nullifier(nullifier.contract_address, nullifier.value())\n }\n}\n\npub fn compute_siloed_private_log_field(contract_address: AztecAddress, field: Field) -> Field {\n poseidon2_hash([contract_address.to_field(), field])\n}\n\npub fn silo_private_log(private_log: Scoped) -> PrivateLog {\n if private_log.contract_address.is_zero() {\n private_log.inner.log\n } else {\n let mut fields = private_log.inner.log.fields;\n fields[0] = compute_siloed_private_log_field(private_log.contract_address, fields[0]);\n PrivateLog { fields }\n }\n}\n\nfn compute_siloed_contract_class_log_hash(address: AztecAddress, log_hash: Field) -> Field {\n accumulate_sha256([address.to_field(), log_hash])\n}\n\npub fn silo_contract_class_log_hash(log_hash: ScopedLogHash) -> Field {\n if log_hash.contract_address.is_zero() {\n 0\n } else {\n compute_siloed_contract_class_log_hash(log_hash.contract_address, log_hash.value())\n }\n}\n\npub fn merkle_hash(left: Field, right: Field) -> Field {\n poseidon2_hash([left, right])\n}\n\npub fn compute_l2_to_l1_hash(\n contract_address: AztecAddress,\n recipient: EthAddress,\n content: Field,\n rollup_version_id: Field,\n chain_id: Field,\n) -> Field {\n let mut bytes: [u8; 160] = std::mem::zeroed();\n\n let inputs =\n [contract_address.to_field(), rollup_version_id, recipient.to_field(), chain_id, content];\n for i in 0..5 {\n // TODO are bytes be in fr.to_buffer() ?\n let item_bytes: [u8; 32] = inputs[i].to_be_bytes();\n for j in 0..32 {\n bytes[32 * i + j] = item_bytes[j];\n }\n }\n\n sha256_to_field(bytes)\n}\n\npub fn silo_l2_to_l1_message(\n msg: ScopedL2ToL1Message,\n rollup_version_id: Field,\n chain_id: Field,\n) -> Field {\n if msg.contract_address.is_zero() {\n 0\n } else {\n compute_l2_to_l1_hash(\n msg.contract_address,\n msg.message.recipient,\n msg.message.content,\n rollup_version_id,\n chain_id,\n )\n }\n}\n\n// Computes sha256 hash of 2 input hashes.\n//\n// NB: This method now takes in two 31 byte fields - it assumes that any input\n// is the result of a sha_to_field hash and => is truncated\n//\n// TODO(Jan and David): This is used for the encrypted_log hashes.\n// Can we check to see if we can just use hash_to_field or pedersen_compress here?\n//\npub fn accumulate_sha256(input: [Field; 2]) -> Field {\n // This is a note about the cpp code, since it takes an array of Fields\n // instead of a U128.\n // 4 Field elements when converted to bytes will usually\n // occupy 4 * 32 = 128 bytes.\n // However, this function is making the assumption that each Field\n // only occupies 128 bits.\n //\n // TODO(David): This does not seem to be getting guaranteed anywhere in the code?\n // Concatentate two fields into 32x2 = 64 bytes\n // accumulate_sha256 assumes that the inputs are pre-truncated 31 byte numbers\n let mut hash_input_flattened = [0; 64];\n for offset in 0..input.len() {\n let input_as_bytes: [u8; 32] = input[offset].to_be_bytes();\n for byte_index in 0..32 {\n hash_input_flattened[offset * 32 + byte_index] = input_as_bytes[byte_index];\n }\n }\n\n sha256_to_field(hash_input_flattened)\n}\n\n// Computes the final logs hash for a tx.\npub fn compute_tx_logs_hash(logs: [LogHash; N]) -> Field {\n // Convert each field element into a byte array and append the bytes to `hash_input_flattened`\n let mut hash_input_flattened = [0; N * 32];\n for offset in 0..N {\n // TODO: This is not checking that the decomposition is smaller than P\n let input_as_bytes: [u8; 32] = logs[offset].value.to_be_radix(256);\n for byte_index in 0..32 {\n hash_input_flattened[offset * 32 + byte_index] = input_as_bytes[byte_index];\n }\n }\n // Ideally we would push to a slice then hash, but there is no sha_slice\n // Hardcode to 256 bytes for now\n let mut hash = sha256_to_field(hash_input_flattened);\n // Not having a 0 value hash for empty logs causes issues with empty txs\n // used for padding. Returning early is currently unsupported.\n // We always provide sorted logs here, so 0 being empty means all are empty.\n if is_empty(logs[0]) {\n hash = 0;\n }\n hash\n}\n\npub fn verification_key_hash(key: [Field; N]) -> Field {\n crate::hash::poseidon2_hash(key)\n}\n\n#[inline_always]\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n std::hash::pedersen_hash_with_separator(inputs, hash_index)\n}\n\npub fn poseidon2_hash(inputs: [Field; N]) -> Field {\n std::hash::poseidon2::Poseidon2::hash(inputs, N)\n}\n\n#[no_predicates]\npub fn poseidon2_hash_with_separator(inputs: [Field; N], separator: T) -> Field\nwhere\n T: ToField,\n{\n let inputs_with_separator = array_concat([separator.to_field()], inputs);\n poseidon2_hash(inputs_with_separator)\n}\n\n// Performs a fixed length hash with a subarray of the given input.\n// Useful for SpongeBlob in which we aborb M things and want to check it vs a hash of M elts of an N-len array.\n// Using stdlib poseidon, this will always absorb an extra 1 as a 'variable' hash, and not match spongeblob.squeeze()\n// or any ts implementation. Also checks that any remaining elts not hashed are empty.\n#[no_predicates]\npub fn poseidon2_hash_subarray(input: [Field; N], in_len: u32) -> Field {\n let mut sponge = poseidon2_absorb_chunks(input, in_len, false);\n sponge.squeeze()\n}\n\n// NB the below is the same as std::hash::poseidon2::Poseidon2::hash(), but replacing a range check with a bit check,\n// and absorbing in chunks of 3 below.\n#[no_predicates]\npub fn poseidon2_cheaper_variable_hash(input: [Field; N], in_len: u32) -> Field {\n let mut sponge = poseidon2_absorb_chunks(input, in_len, true);\n // In the case where the hash preimage is variable-length, we append `1` to the end of the input, to distinguish\n // from fixed-length hashes. (the combination of this additional field element + the hash IV ensures\n // fixed-length and variable-length hashes do not collide)\n if in_len != N {\n sponge.absorb(1);\n }\n sponge.squeeze()\n}\n\n// The below fn reduces gates of a conditional poseidon2 hash by approx 3x (thank you ~* Giant Brain Dev @IlyasRidhuan *~ for the idea)\n// Why? Because when we call stdlib poseidon, we call absorb for each item. When absorbing is conditional, it seems the compiler does not know\n// what cache_size will be when calling absorb, so it assigns the permutation gates for /each i/ rather than /every 3rd i/, which is actually required.\n// The below code forces the compiler to:\n// - absorb normally up to 2 times to set cache_size to 1\n// - absorb in chunks of 3 to ensure perm. only happens every 3rd absorb\n// - absorb normally up to 2 times to add any remaining values to the hash\n// In fixed len hashes, the compiler is able to tell that it will only need to perform the permutation every 3 absorbs.\n// NB: it also replaces unnecessary range checks (i < thing) with a bit check (&= i != thing), which alone reduces the gates of a var. hash by half.\n\n#[no_predicates]\nfn poseidon2_absorb_chunks(\n input: [Field; N],\n in_len: u32,\n variable: bool,\n) -> Poseidon2Sponge {\n let iv: Field = (in_len as Field) * TWO_POW_64;\n let mut sponge = Poseidon2Sponge::new(iv);\n // Even though shift is always 1 here, if we input in_len = 0 we get an underflow\n // since we cannot isolate computation branches. The below is just to avoid that.\n let shift = if in_len == 0 { 0 } else { 1 };\n if in_len != 0 {\n // cache_size = 0, init absorb\n sponge.cache[0] = input[0];\n sponge.cache_size = 1;\n // shift = num elts already added to make cache_size 1 = 1 for a fresh sponge\n // M = max_chunks = (N - 1 - (N - 1) % 3) / 3: (must be written as a fn of N to compile)\n // max_remainder = (N - 1) % 3;\n // max_chunks = (N - 1 - max_remainder) / 3;\n sponge = poseidon2_absorb_chunks_loop::(\n sponge,\n input,\n in_len,\n variable,\n shift,\n );\n }\n sponge\n}\n\n// NB: If it's not required to check that the non-absorbed elts of 'input' are 0s, set skip_0_check=true\n#[no_predicates]\npub fn poseidon2_absorb_chunks_existing_sponge(\n in_sponge: Poseidon2Sponge,\n input: [Field; N],\n in_len: u32,\n skip_0_check: bool,\n) -> Poseidon2Sponge {\n let mut sponge = in_sponge;\n // 'shift' is to account for already added inputs\n let mut shift = 0;\n // 'stop' is to avoid an underflow when inputting in_len = 0\n let mut stop = false;\n for i in 0..3 {\n if shift == in_len {\n stop = true;\n }\n if (sponge.cache_size != 1) & (!stop) {\n sponge.absorb(input[i]);\n shift += 1;\n }\n }\n sponge = if stop {\n sponge\n } else {\n // max_chunks = (N - (N % 3)) / 3;\n poseidon2_absorb_chunks_loop::(\n sponge,\n input,\n in_len,\n skip_0_check,\n shift,\n )\n };\n sponge\n}\n\n// The below is the loop to absorb elts into a poseidon sponge in chunks of 3\n// shift - the num of elts already absorbed to ensure the sponge's cache_size = 1\n// M - the max number of chunks required to absorb N things (must be comptime to compile)\n// NB: The 0 checks ('Found non-zero field...') are messy, but having a separate loop over N to check\n// for 0s costs 3N gates. Current approach is approx 2N gates.\n#[no_predicates]\nfn poseidon2_absorb_chunks_loop(\n in_sponge: Poseidon2Sponge,\n input: [Field; N],\n in_len: u32,\n variable: bool,\n shift: u32,\n) -> Poseidon2Sponge {\n assert(in_len <= N, \"Given in_len to absorb is larger than the input array len\");\n // When we have an existing sponge, we may have a shift of 0, and the final 'k+2' below = N\n // The below avoids an overflow\n let skip_last = 3 * M == N;\n // Writing in_sponge: &mut does not compile\n let mut sponge = in_sponge;\n let mut should_add = true;\n // The num of things left over after absorbing in 3s\n let remainder = (in_len - shift) % 3;\n // The num of chunks of 3 to absorb (maximum M)\n let chunks = (in_len - shift - remainder) / 3;\n for i in 0..M {\n // Now we loop through cache size = 1 -> 3\n should_add &= i != chunks;\n // This is the index at the start of the chunk (for readability)\n let k = 3 * i + shift;\n if should_add {\n // cache_size = 1, 2 => just assign\n sponge.cache[1] = input[k];\n sponge.cache[2] = input[k + 1];\n // cache_size = 3 => duplex + perm\n for j in 0..3 {\n sponge.state[j] += sponge.cache[j];\n }\n sponge.state = std::hash::poseidon2_permutation(sponge.state, 4);\n sponge.cache[0] = input[k + 2];\n // cache_size is now 1 again, repeat loop\n } else if (!variable) & (i != chunks) {\n // if we are hashing a fixed len array which is a subarray, we check the remaining elts are 0\n // NB: we don't check at i == chunks, because that chunk contains elts to be absorbed or checked below\n let last_0 = if (i == M - 1) & (skip_last) {\n 0\n } else {\n input[k + 2]\n };\n let all_0 = (input[k] == 0) & (input[k + 1] == 0) & (last_0 == 0);\n assert(all_0, \"Found non-zero field after breakpoint\");\n }\n }\n // we have 'remainder' num of items left to absorb\n should_add = true;\n // below is to avoid overflows (i.e. if inlen is close to N)\n let mut should_check = !variable;\n for i in 0..3 {\n should_add &= i != remainder;\n should_check &= in_len - remainder + i != N;\n if should_add {\n // we want to absorb the final 'remainder' items\n sponge.absorb(input[in_len - remainder + i]);\n } else if should_check {\n assert(input[in_len - remainder + i] == 0, \"Found non-zero field after breakpoint\");\n }\n }\n sponge\n}\n\npub fn poseidon2_hash_with_separator_slice(inputs: [Field], separator: T) -> Field\nwhere\n T: ToField,\n{\n let in_len = inputs.len() + 1;\n let iv: Field = (in_len as Field) * TWO_POW_64;\n let mut sponge = Poseidon2Sponge::new(iv);\n sponge.absorb(separator.to_field());\n\n for i in 0..inputs.len() {\n sponge.absorb(inputs[i]);\n }\n\n sponge.squeeze()\n}\n\n#[no_predicates]\npub fn poseidon2_hash_bytes(inputs: [u8; N]) -> Field {\n let mut fields = [0; (N + 30) / 31];\n let mut field_index = 0;\n let mut current_field = [0; 31];\n for i in 0..inputs.len() {\n let index = i % 31;\n current_field[index] = inputs[i];\n if index == 30 {\n fields[field_index] = field_from_bytes(current_field, false);\n current_field = [0; 31];\n field_index += 1;\n }\n }\n if field_index != fields.len() {\n fields[field_index] = field_from_bytes(current_field, false);\n }\n poseidon2_hash(fields)\n}\n\n#[test]\nfn poseidon_chunks_matches_fixed() {\n let in_len = 501;\n let mut input: [Field; 4096] = [0; 4096];\n let mut fixed_input = [3; 501];\n assert(in_len == fixed_input.len()); // sanity check\n for i in 0..in_len {\n input[i] = 3;\n }\n let sub_chunk_hash = poseidon2_hash_subarray(input, in_len);\n let fixed_len_hash = std::hash::poseidon2::Poseidon2::hash(fixed_input, fixed_input.len());\n assert(sub_chunk_hash == fixed_len_hash);\n}\n\n#[test]\nfn poseidon_chunks_matches_variable() {\n let in_len = 501;\n let mut input: [Field; 4096] = [0; 4096];\n for i in 0..in_len {\n input[i] = 3;\n }\n let variable_chunk_hash = poseidon2_cheaper_variable_hash(input, in_len);\n let variable_len_hash = std::hash::poseidon2::Poseidon2::hash(input, in_len);\n assert(variable_chunk_hash == variable_len_hash);\n}\n\n#[test]\nfn existing_sponge_poseidon_chunks_matches_fixed() {\n let in_len = 501;\n let mut input: [Field; 4096] = [0; 4096];\n let mut fixed_input = [3; 501];\n assert(in_len == fixed_input.len()); // sanity check\n for i in 0..in_len {\n input[i] = 3;\n }\n // absorb 250 of the 501 things\n let empty_sponge = Poseidon2Sponge::new((in_len as Field) * TWO_POW_64);\n let first_sponge = poseidon2_absorb_chunks_existing_sponge(empty_sponge, input, 250, true);\n // now absorb the final 251 (since they are all 3s, im being lazy and not making a new array)\n let mut final_sponge = poseidon2_absorb_chunks_existing_sponge(first_sponge, input, 251, true);\n let fixed_len_hash = Poseidon2Sponge::hash(fixed_input, fixed_input.len());\n assert(final_sponge.squeeze() == fixed_len_hash);\n}\n\n#[test]\nfn poseidon_chunks_empty_inputs() {\n let in_len = 0;\n let mut input: [Field; 4096] = [0; 4096];\n let mut constructed_empty_sponge = poseidon2_absorb_chunks(input, in_len, true);\n let mut first_sponge =\n poseidon2_absorb_chunks_existing_sponge(constructed_empty_sponge, input, in_len, true);\n assert(first_sponge.squeeze() == constructed_empty_sponge.squeeze());\n}\n\n#[test]\nfn smoke_sha256_to_field() {\n let full_buffer = [\n 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,\n 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,\n 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,\n 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,\n 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,\n 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,\n 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,\n ];\n let result = sha256_to_field(full_buffer);\n\n assert(result == 0x448ebbc9e1a31220a2f3830c18eef61b9bd070e5084b7fa2a359fe729184c7);\n\n // to show correctness of the current ver (truncate one byte) vs old ver (mod full bytes):\n let result_bytes = std::hash::sha256(full_buffer);\n let truncated_field = crate::utils::field::field_from_bytes_32_trunc(result_bytes);\n assert(truncated_field == result);\n let mod_res = result + (result_bytes[31] as Field);\n assert(mod_res == 0x448ebbc9e1a31220a2f3830c18eef61b9bd070e5084b7fa2a359fe729184e0);\n}\n\n#[test]\nfn compute_l2_l1_hash() {\n // All zeroes\n let hash_result =\n compute_l2_to_l1_hash(AztecAddress::from_field(0), EthAddress::zero(), 0, 0, 0);\n assert(hash_result == 0xb393978842a0fa3d3e1470196f098f473f9678e72463cb65ec4ab5581856c2);\n\n // Non-zero case\n let hash_result = compute_l2_to_l1_hash(\n AztecAddress::from_field(1),\n EthAddress::from_field(3),\n 5,\n 2,\n 4,\n );\n assert(hash_result == 0x3f88c1044a05e5340ed20466276500f6d45ca5603913b9091e957161734e16);\n}\n\n#[test]\nfn silo_l2_to_l1_message_matches_typescript() {\n let version = 4;\n let chainId = 5;\n\n let hash = silo_l2_to_l1_message(\n ScopedL2ToL1Message {\n message: L2ToL1Message { recipient: EthAddress::from_field(1), content: 2, counter: 0 },\n contract_address: AztecAddress::from_field(3),\n },\n version,\n chainId,\n );\n\n // The following value was generated by `l2_to_l1_message.test.ts`\n let hash_from_typescript = 0x00c6155d69febb9d5039b374dd4f77bf57b7c881709aa524a18acaa0bd57476a;\n\n assert_eq(hash, hash_from_typescript);\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr"},"280":{"source":"use crate::{hash::poseidon2_hash, traits::ToField};\n\npub fn derive_storage_slot_in_map(storage_slot: Field, key: K) -> Field\nwhere\n K: ToField,\n{\n poseidon2_hash([storage_slot, key.to_field()])\n}\n\nmod test {\n use crate::{address::AztecAddress, storage::map::derive_storage_slot_in_map, traits::FromField};\n\n #[test]\n fn test_derive_storage_slot_in_map_matches_typescript() {\n let map_slot = 0x132258fb6962c4387ba659d9556521102d227549a386d39f0b22d1890d59c2b5;\n let key = AztecAddress::from_field(\n 0x302dbc2f9b50a73283d5fb2f35bc01eae8935615817a0b4219a057b2ba8a5a3f,\n );\n\n let slot = derive_storage_slot_in_map(map_slot, key);\n\n // The following value was generated by `map_slot.test.ts`\n let slot_from_typescript =\n 0x15b9fe39449affd8b377461263e9d2b610b9ad40580553500b4e41d9cbd887ac;\n\n assert_eq(slot, slot_from_typescript);\n }\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/noir-protocol-circuits/crates/types/src/storage/map.nr"},"293":{"source":"use crate::meta::{derive_deserialize, derive_serialize};\nuse crate::utils::field::field_from_bytes;\n\n// Trait: is_empty\n//\n// The general is_empty trait checks if a data type is is empty,\n// and it defines empty for the basic data types as 0.\n//\n// If a Field is equal to zero, then it is regarded as zero.\n// We will go with this definition for now, however it can be problematic\n// if a value can actually be zero. In a future refactor, we can\n// use the optional type for safety. Doing it now would lead to a worse devex\n// and would make it harder to sync up with the cpp code.\n// Preferred over Default trait to convey intent, as default doesn't necessarily mean empty.\npub trait Empty {\n fn empty() -> Self;\n}\n\nimpl Empty for Field {\n fn empty() -> Self {\n 0\n }\n}\n\nimpl Empty for u1 {\n fn empty() -> Self {\n 0\n }\n}\nimpl Empty for u8 {\n fn empty() -> Self {\n 0\n }\n}\nimpl Empty for u32 {\n fn empty() -> Self {\n 0\n }\n}\nimpl Empty for u64 {\n fn empty() -> Self {\n 0\n }\n}\nimpl Empty for U128 {\n fn empty() -> Self {\n U128::from_integer(0)\n }\n}\n\npub fn is_empty(item: T) -> bool\nwhere\n T: Empty + Eq,\n{\n item.eq(T::empty())\n}\n\npub fn is_empty_array(array: [T; N]) -> bool\nwhere\n T: Empty + Eq,\n{\n array.all(|elem| is_empty(elem))\n}\n\npub trait Hash {\n fn hash(self) -> Field;\n}\n\npub trait ToField {\n fn to_field(self) -> Field;\n}\n\nimpl ToField for Field {\n fn to_field(self) -> Field {\n self\n }\n}\n\nimpl ToField for bool {\n fn to_field(self) -> Field {\n self as Field\n }\n}\nimpl ToField for u1 {\n fn to_field(self) -> Field {\n self as Field\n }\n}\nimpl ToField for u8 {\n fn to_field(self) -> Field {\n self as Field\n }\n}\nimpl ToField for u32 {\n fn to_field(self) -> Field {\n self as Field\n }\n}\nimpl ToField for u64 {\n fn to_field(self) -> Field {\n self as Field\n }\n}\nimpl ToField for U128 {\n fn to_field(self) -> Field {\n self.to_integer()\n }\n}\nimpl ToField for str {\n fn to_field(self) -> Field {\n assert(N < 32, \"String doesn't fit in a field, consider using Serialize instead\");\n field_from_bytes(self.as_bytes(), true)\n }\n}\n\npub trait FromField {\n fn from_field(value: Field) -> Self;\n}\n\nimpl FromField for Field {\n fn from_field(value: Field) -> Self {\n value\n }\n}\n\nimpl FromField for bool {\n fn from_field(value: Field) -> Self {\n value as bool\n }\n}\nimpl FromField for u1 {\n fn from_field(value: Field) -> Self {\n value as u1\n }\n}\nimpl FromField for u8 {\n fn from_field(value: Field) -> Self {\n value as u8\n }\n}\nimpl FromField for u32 {\n fn from_field(value: Field) -> Self {\n value as u32\n }\n}\nimpl FromField for u64 {\n fn from_field(value: Field) -> Self {\n value as u64\n }\n}\nimpl FromField for U128 {\n fn from_field(value: Field) -> Self {\n U128::from_integer(value)\n }\n}\n\n// docs:start:serialize\n/// Trait for serializing Noir types into arrays of Fields.\n///\n/// An implementation of the Serialize trait has to follow Noir's intrinsic serialization (each member of a struct\n/// converted directly into one or more Fields without any packing or compression). This trait (and Deserialize) are\n/// typically used to communicate between Noir and TypeScript (via oracles and function arguments).\n///\n/// # On Following Noir's Intrinsic Serialization\n/// When calling a Noir function from TypeScript (TS), first the function arguments are serialized into an array\n/// of fields. This array is then included in the initial witness. Noir's intrinsic serialization is then used\n/// to deserialize the arguments from the witness. When the same Noir function is called from Noir this Serialize trait\n/// is used instead of the serialization in TS. For this reason we need to have a match between TS serialization,\n/// Noir's intrinsic serialization and the implementation of this trait. If there is a mismatch, the function calls\n/// fail with an arguments hash mismatch error message.\n///\n/// # Type Parameters\n/// * `N` - The length of the output Field array, known at compile time\n///\n/// # Example\n/// ```\n/// impl Serialize for str {\n/// fn serialize(self) -> [Field; N] {\n/// let bytes = self.as_bytes();\n/// let mut fields = [0; N];\n/// for i in 0..bytes.len() {\n/// fields[i] = bytes[i] as Field; // Each byte gets its own Field\n/// }\n/// fields\n/// }\n/// }\n/// ```\n#[derive_via(derive_serialize)]\npub trait Serialize {\n fn serialize(self) -> [Field; N];\n}\n// docs:end:serialize\n\nimpl Serialize for str {\n fn serialize(self) -> [Field; N] {\n let bytes = self.as_bytes();\n let mut fields = [0; N];\n for i in 0..bytes.len() {\n fields[i] = bytes[i] as Field;\n }\n fields\n }\n}\n\n// docs:start:deserialize\n/// Trait for deserializing Noir types from arrays of Fields.\n///\n/// An implementation of the Deserialize trait has to follow Noir's intrinsic serialization (each member of a struct\n/// converted directly into one or more Fields without any packing or compression). This trait is typically used when\n/// deserializing return values from function calls in Noir. Since the same function could be called from TypeScript\n/// (TS), in which case the TS deserialization would get used, we need to have a match between the 2.\n///\n/// # Type Parameters\n/// * `N` - The length of the input Field array, known at compile time\n///\n/// # Example\n/// ```\n/// impl Deserialize for str {\n/// fn deserialize(fields: [Field; N]) -> Self {\n/// str::from(fields.map(|value| value as u8))\n/// }\n/// }\n/// ```\n#[derive_via(derive_deserialize)]\npub trait Deserialize {\n fn deserialize(fields: [Field; N]) -> Self;\n}\n// docs:end:deserialize\n\nimpl Deserialize for str {\n fn deserialize(fields: [Field; N]) -> Self {\n str::from(fields.map(|value| value as u8))\n }\n}\n\n/// Trait for efficiently packing and unpacking Noir types into and from arrays of Fields.\n///\n/// The `Packable` trait allows types to be serialized and deserialized with a focus on minimizing the size of\n/// the resulting Field array. This trait is used when storage efficiency is critical (e.g. when storing data\n/// in the contract's public storage).\n///\n/// # Type Parameters\n/// * `N` - The length of the Field array, known at compile time.\npub trait Packable {\n /// Packs the current value into a compact array of `Field` elements.\n fn pack(self) -> [Field; N];\n\n /// Unpacks a compact array of `Field` elements into the original value.\n fn unpack(fields: [Field; N]) -> Self;\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/noir-protocol-circuits/crates/types/src/traits.nr"},"297":{"source":"use crate::traits::{Packable, ToField};\n\nglobal BOOL_PACKED_LEN: u32 = 1;\nglobal U8_PACKED_LEN: u32 = 1;\nglobal U16_PACKED_LEN: u32 = 1;\nglobal U32_PACKED_LEN: u32 = 1;\nglobal U64_PACKED_LEN: u32 = 1;\nglobal U128_PACKED_LEN: u32 = 1;\nglobal FIELD_PACKED_LEN: u32 = 1;\nglobal I8_PACKED_LEN: u32 = 1;\nglobal I16_PACKED_LEN: u32 = 1;\nglobal I32_PACKED_LEN: u32 = 1;\nglobal I64_PACKED_LEN: u32 = 1;\n\nimpl Packable for bool {\n fn pack(self) -> [Field; BOOL_PACKED_LEN] {\n [self as Field]\n }\n\n fn unpack(fields: [Field; BOOL_PACKED_LEN]) -> bool {\n fields[0] as bool\n }\n}\n\nimpl Packable for u8 {\n fn pack(self) -> [Field; U8_PACKED_LEN] {\n [self as Field]\n }\n\n fn unpack(fields: [Field; U8_PACKED_LEN]) -> Self {\n fields[0] as u8\n }\n}\n\nimpl Packable for u16 {\n fn pack(self) -> [Field; U16_PACKED_LEN] {\n [self as Field]\n }\n\n fn unpack(fields: [Field; U16_PACKED_LEN]) -> Self {\n fields[0] as u16\n }\n}\n\nimpl Packable for u32 {\n fn pack(self) -> [Field; U32_PACKED_LEN] {\n [self as Field]\n }\n\n fn unpack(fields: [Field; U32_PACKED_LEN]) -> Self {\n fields[0] as u32\n }\n}\n\nimpl Packable for u64 {\n fn pack(self) -> [Field; U64_PACKED_LEN] {\n [self as Field]\n }\n\n fn unpack(fields: [Field; U64_PACKED_LEN]) -> Self {\n fields[0] as u64\n }\n}\n\nimpl Packable for U128 {\n fn pack(self) -> [Field; U128_PACKED_LEN] {\n [self.to_field()]\n }\n\n fn unpack(fields: [Field; U128_PACKED_LEN]) -> Self {\n U128::from_integer(fields[0])\n }\n}\n\nimpl Packable for Field {\n fn pack(self) -> [Field; FIELD_PACKED_LEN] {\n [self]\n }\n\n fn unpack(fields: [Field; FIELD_PACKED_LEN]) -> Self {\n fields[0]\n }\n}\n\nimpl Packable for i8 {\n fn pack(self) -> [Field; I8_PACKED_LEN] {\n [self as Field]\n }\n\n fn unpack(fields: [Field; I8_PACKED_LEN]) -> Self {\n fields[0] as i8\n }\n}\n\nimpl Packable for i16 {\n fn pack(self) -> [Field; I16_PACKED_LEN] {\n [self as Field]\n }\n\n fn unpack(fields: [Field; I16_PACKED_LEN]) -> Self {\n fields[0] as i16\n }\n}\n\nimpl Packable for i32 {\n fn pack(self) -> [Field; I32_PACKED_LEN] {\n [self as Field]\n }\n\n fn unpack(fields: [Field; I32_PACKED_LEN]) -> Self {\n fields[0] as i32\n }\n}\n\nimpl Packable for i64 {\n fn pack(self) -> [Field; I64_PACKED_LEN] {\n [self as Field]\n }\n\n fn unpack(fields: [Field; I64_PACKED_LEN]) -> Self {\n fields[0] as i64\n }\n}\n\nimpl Packable for [T; N]\nwhere\n T: Packable,\n{\n fn pack(self) -> [Field; N * M] {\n let mut result: [Field; N * M] = std::mem::zeroed();\n let mut serialized: [Field; M] = std::mem::zeroed();\n for i in 0..N {\n serialized = self[i].pack();\n for j in 0..M {\n result[i * M + j] = serialized[j];\n }\n }\n result\n }\n\n fn unpack(fields: [Field; N * M]) -> Self {\n let mut reader = crate::utils::reader::Reader::new(fields);\n let mut result: [T; N] = std::mem::zeroed();\n reader.read_struct_array::(Packable::unpack, result)\n }\n}\n\n#[test]\nfn test_u16_packing() {\n let a: u16 = 10;\n assert_eq(a, u16::unpack(a.pack()));\n}\n\n#[test]\nfn test_i8_packing() {\n let a: i8 = -10;\n assert_eq(a, i8::unpack(a.pack()));\n}\n\n#[test]\nfn test_i16_packing() {\n let a: i16 = -10;\n assert_eq(a, i16::unpack(a.pack()));\n}\n\n#[test]\nfn test_i32_packing() {\n let a: i32 = -10;\n assert_eq(a, i32::unpack(a.pack()));\n}\n\n#[test]\nfn test_i64_packing() {\n let a: i64 = -10;\n assert_eq(a, i64::unpack(a.pack()));\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/noir-protocol-circuits/crates/types/src/type_packing.nr"},"314":{"source":"pub mod assert_array_appended;\npub mod assert_array_prepended;\npub mod assert_combined_array;\npub mod assert_combined_transformed_array;\npub mod assert_exposed_sorted_transformed_value_array;\npub mod assert_sorted_array;\npub mod assert_sorted_transformed_value_array;\npub mod assert_split_sorted_transformed_value_arrays;\npub mod assert_split_transformed_value_arrays;\npub mod get_sorted_result;\npub mod get_sorted_tuple;\npub mod sort_by;\npub mod sort_by_counter;\n\n// Re-exports.\npub use assert_array_appended::{\n assert_array_appended, assert_array_appended_and_scoped, assert_array_appended_reversed,\n assert_array_appended_scoped,\n};\npub use assert_array_prepended::assert_array_prepended;\npub use assert_combined_array::{assert_combined_array, combine_arrays};\npub use assert_combined_transformed_array::{\n assert_combined_transformed_array, combine_and_transform_arrays,\n};\npub use assert_exposed_sorted_transformed_value_array::{\n assert_exposed_sorted_transformed_value_array,\n get_order_hints::{get_order_hints_asc, get_order_hints_desc, OrderHint},\n};\npub use assert_sorted_array::assert_sorted_array;\npub use assert_sorted_transformed_value_array::{\n assert_sorted_transformed_value_array, assert_sorted_transformed_value_array_capped_size,\n};\npub use assert_split_sorted_transformed_value_arrays::{\n assert_split_sorted_transformed_value_arrays_asc,\n assert_split_sorted_transformed_value_arrays_desc,\n get_split_order_hints::{get_split_order_hints_asc, get_split_order_hints_desc, SplitOrderHints},\n};\npub use assert_split_transformed_value_arrays::assert_split_transformed_value_arrays;\npub use get_sorted_result::{get_sorted_result, SortedResult};\npub use sort_by_counter::{sort_by_counter_asc, sort_by_counter_desc};\n\nuse crate::traits::{Empty, is_empty};\n\npub fn subarray(\n src: [Field; SRC_LEN],\n offset: u32,\n) -> [Field; DST_LEN] {\n assert(offset + DST_LEN <= SRC_LEN, \"offset too large\");\n\n let mut dst: [Field; DST_LEN] = std::mem::zeroed();\n for i in 0..DST_LEN {\n dst[i] = src[i + offset];\n }\n\n dst\n}\n\n// Helper function to convert a validated array to BoundedVec.\n// Important: Only use it for validated arrays: validate_array(array) should be true.\npub unconstrained fn array_to_bounded_vec(array: [T; N]) -> BoundedVec\nwhere\n T: Empty + Eq,\n{\n let len = array_length(array);\n BoundedVec::from_parts_unchecked(array, len)\n}\n\n// Helper function to find the index of the first element in an array that satisfies a given predicate. If the element\n// is not found, the function returns N as the index.\npub unconstrained fn find_index_hint(\n array: [T; N],\n find: fn[Env](T) -> bool,\n) -> u32 {\n let mut index = N;\n for i in 0..N {\n // We check `index == N` to ensure that we only update the index if we haven't found a match yet.\n if (index == N) & find(array[i]) {\n index = i;\n }\n }\n index\n}\n\n// Routine which validates that all zero values of an array form a contiguous region at the end, i.e.,\n// of the form: [*,*,*...,0,0,0,0] where any * is non-zero. Note that a full array of non-zero values is\n// valid.\npub fn validate_array(array: [T; N]) -> u32\nwhere\n T: Empty + Eq,\n{\n let mut seen_empty = false;\n let mut length = 0;\n for i in 0..N {\n if is_empty(array[i]) {\n seen_empty = true;\n } else {\n assert(seen_empty == false, \"invalid array\");\n length += 1;\n }\n }\n length\n}\n\n// Helper function to count the number of non-empty elements in a validated array.\n// Important: Only use it for validated arrays where validate_array(array) returns true,\n// which ensures that:\n// 1. All elements before the first empty element are non-empty\n// 2. All elements after and including the first empty element are empty\n// 3. The array forms a contiguous sequence of non-empty elements followed by empty elements\npub fn array_length(array: [T; N]) -> u32\nwhere\n T: Empty + Eq,\n{\n // We get the length by checking the index of the first empty element.\n\n /// Safety: This is safe because we have validated the array (see function doc above) and the emptiness\n /// of the element and non-emptiness of the previous element is checked below.\n let length = unsafe { find_index_hint(array, |elem: T| is_empty(elem)) };\n if length != 0 {\n assert(!is_empty(array[length - 1]));\n }\n if length != N {\n assert(is_empty(array[length]));\n }\n length\n}\n\npub fn array_concat(array1: [T; N], array2: [T; M]) -> [T; N + M] {\n let mut result = [array1[0]; N + M];\n for i in 1..N {\n result[i] = array1[i];\n }\n for i in 0..M {\n result[i + N] = array2[i];\n }\n result\n}\n\npub fn array_merge(array1: [T; N], array2: [T; N]) -> [T; N]\nwhere\n T: Empty + Eq,\n{\n let mut result: [T; N] = [T::empty(); N];\n let mut i = 0;\n for elem in array1 {\n if !is_empty(elem) {\n result[i] = elem;\n i += 1;\n }\n }\n for elem in array2 {\n if !is_empty(elem) {\n result[i] = elem;\n i += 1;\n }\n }\n result\n}\n\n// Helper fn to create a subarray from a given array\npub fn array_splice(array: [T; N], offset: u32) -> [T; M]\nwhere\n T: Empty,\n{\n assert(M + offset <= N, \"Subarray length larger than array length\");\n let mut result: [T; M] = [T::empty(); M];\n for i in 0..M {\n result[i] = array[offset + i];\n }\n result\n}\n\npub fn check_permutation(\n original_array: [T; N],\n permuted_array: [T; N],\n original_indexes: [u32; N],\n)\nwhere\n T: Eq + Empty,\n{\n let mut seen_value = [false; N];\n for i in 0..N {\n let index = original_indexes[i];\n let original_value = original_array[index];\n assert(permuted_array[i].eq(original_value), \"Invalid index\");\n assert(!seen_value[index], \"Duplicated index\");\n seen_value[index] = true;\n }\n}\n\n#[test]\nfn smoke_validate_array() {\n let valid_array: [Field; 0] = [];\n assert(validate_array(valid_array) == 0);\n\n let valid_array = [0];\n assert(validate_array(valid_array) == 0);\n\n let valid_array = [3];\n assert(validate_array(valid_array) == 1);\n\n let valid_array = [1, 2, 3];\n assert(validate_array(valid_array) == 3);\n\n let valid_array = [1, 2, 3, 0];\n assert(validate_array(valid_array) == 3);\n\n let valid_array = [1, 2, 3, 0, 0];\n assert(validate_array(valid_array) == 3);\n}\n\n#[test(should_fail_with = \"invalid array\")]\nfn smoke_validate_array_invalid_case0() {\n let invalid_array = [0, 1];\n let _ = validate_array(invalid_array);\n}\n\n#[test(should_fail_with = \"invalid array\")]\nfn smoke_validate_array_invalid_case1() {\n let invalid_array = [1, 0, 0, 1, 0];\n let _ = validate_array(invalid_array);\n}\n\n#[test(should_fail_with = \"invalid array\")]\nfn smoke_validate_array_invalid_case2() {\n let invalid_array = [0, 0, 0, 0, 1];\n let _ = validate_array(invalid_array);\n}\n\n#[test]\nfn test_empty_array_length() {\n assert_eq(array_length([0]), 0);\n assert_eq(array_length([0, 0, 0]), 0);\n}\n\n#[test]\nfn test_array_length() {\n assert_eq(array_length([123]), 1);\n assert_eq(array_length([123, 0, 0]), 1);\n assert_eq(array_length([123, 456]), 2);\n assert_eq(array_length([123, 456, 0]), 2);\n}\n\n#[test]\nfn test_array_length_invalid_arrays() {\n // Result can be misleading (but correct) for invalid arrays.\n assert_eq(array_length([0, 0, 123]), 0);\n assert_eq(array_length([0, 123, 0]), 0);\n assert_eq(array_length([0, 123, 456]), 0);\n assert_eq(array_length([123, 0, 456]), 1);\n}\n\n#[test]\nunconstrained fn find_index_greater_than_min() {\n let values = [10, 20, 30, 40];\n let min = 22;\n let index = find_index_hint(values, |v: Field| min.lt(v));\n assert_eq(index, 2);\n}\n\n#[test]\nunconstrained fn find_index_not_found() {\n let values = [10, 20, 30, 40];\n let min = 100;\n let index = find_index_hint(values, |v: Field| min.lt(v));\n assert_eq(index, 4);\n}\n\n#[test]\nfn test_array_concat() {\n let array0 = [1, 2, 3];\n let array1 = [4, 5];\n let concatenated = array_concat(array0, array1);\n assert_eq(concatenated, [1, 2, 3, 4, 5]);\n}\n\n#[test]\nfn check_permutation_basic_test() {\n let original_array = [1, 2, 3];\n let permuted_array = [3, 1, 2];\n let indexes = [2, 0, 1];\n check_permutation(original_array, permuted_array, indexes);\n}\n\n#[test(should_fail_with = \"Duplicated index\")]\nfn check_permutation_duplicated_index() {\n let original_array = [0, 1, 0];\n let permuted_array = [1, 0, 0];\n let indexes = [1, 0, 0];\n check_permutation(original_array, permuted_array, indexes);\n}\n\n#[test(should_fail_with = \"Invalid index\")]\nfn check_permutation_invalid_index() {\n let original_array = [0, 1, 2];\n let permuted_array = [1, 0, 0];\n let indexes = [1, 0, 2];\n check_permutation(original_array, permuted_array, indexes);\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr"},"317":{"source":"pub struct Reader {\n data: [Field; N],\n offset: u32,\n}\n\nimpl Reader {\n pub fn new(data: [Field; N]) -> Self {\n Self { data, offset: 0 }\n }\n\n pub fn read(&mut self) -> Field {\n let result = self.data[self.offset];\n self.offset += 1;\n result\n }\n\n pub fn read_u32(&mut self) -> u32 {\n self.read() as u32\n }\n\n pub fn read_bool(&mut self) -> bool {\n self.read() as bool\n }\n\n pub fn read_array(&mut self) -> [Field; K] {\n let mut result = [0; K];\n for i in 0..K {\n result[i] = self.data[self.offset + i];\n }\n self.offset += K;\n result\n }\n\n pub fn read_struct(&mut self, deserialise: fn([Field; K]) -> T) -> T {\n let result = deserialise(self.read_array());\n result\n }\n\n pub fn read_struct_array(\n &mut self,\n deserialise: fn([Field; K]) -> T,\n mut result: [T; C],\n ) -> [T; C] {\n for i in 0..C {\n result[i] = self.read_struct(deserialise);\n }\n result\n }\n\n pub fn finish(self) {\n assert(self.offset == self.data.len(), \"Reader did not read all data\");\n }\n}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.72.1/noir-projects/noir-protocol-circuits/crates/types/src/utils/reader.nr"}}} \ No newline at end of file diff --git a/services/explorer-api/migrations/0000_concerned_frank_castle.sql b/services/explorer-api/migrations/0000_public_firedrake.sql similarity index 91% rename from services/explorer-api/migrations/0000_concerned_frank_castle.sql rename to services/explorer-api/migrations/0000_public_firedrake.sql index 997e9986d..1e7f64943 100644 --- a/services/explorer-api/migrations/0000_concerned_frank_castle.sql +++ b/services/explorer-api/migrations/0000_public_firedrake.sql @@ -32,21 +32,6 @@ CREATE TABLE IF NOT EXISTS "body" ( "block_hash" varchar NOT NULL ); --> statement-breakpoint -CREATE TABLE IF NOT EXISTS "function_logs" ( - "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, - "index" integer NOT NULL, - "tx_effect_to_logs_id" uuid NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "logs" ( - "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, - "index" integer NOT NULL, - "tx_effect_to_logs_id" uuid NOT NULL, - "type" varchar(20) NOT NULL, - "data" "bytea" NOT NULL, - "contract_address" varchar(66) -); ---> statement-breakpoint CREATE TABLE IF NOT EXISTS "public_data_write" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "tx_effect_hash" varchar NOT NULL, @@ -65,13 +50,10 @@ CREATE TABLE IF NOT EXISTS "tx_effect" ( "note_hashes" jsonb NOT NULL, "nullifiers" jsonb NOT NULL, "l2_to_l1_msgs" jsonb NOT NULL, - "unencrypted_logs_length" bigint NOT NULL, - "private_logs" jsonb NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "tx_effect_to_logs" ( - "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, - "tx_effect_hash" varchar NOT NULL + "contract_class_logs_length" bigint NOT NULL, + "private_logs" jsonb NOT NULL, + "public_logs" jsonb NOT NULL, + "contract_class_logs" jsonb NOT NULL ); --> statement-breakpoint CREATE TABLE IF NOT EXISTS "content_commitment" ( @@ -105,7 +87,8 @@ CREATE TABLE IF NOT EXISTS "global_variables" ( CREATE TABLE IF NOT EXISTS "header" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "block_hash" varchar NOT NULL, - "total_fees" bigint NOT NULL + "total_fees" bigint NOT NULL, + "total_mana_used" bigint NOT NULL ); --> statement-breakpoint CREATE TABLE IF NOT EXISTS "l1_to_l2_message_tree" ( @@ -309,18 +292,6 @@ EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "function_logs" ADD CONSTRAINT "function_logs_tx_effect_to_logs_id_tx_effect_to_logs_id_fk" FOREIGN KEY ("tx_effect_to_logs_id") REFERENCES "public"."tx_effect_to_logs"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "logs" ADD CONSTRAINT "logs_tx_effect_to_logs_id_tx_effect_to_logs_id_fk" FOREIGN KEY ("tx_effect_to_logs_id") REFERENCES "public"."tx_effect_to_logs"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint DO $$ BEGIN ALTER TABLE "public_data_write" ADD CONSTRAINT "public_data_write_tx_effect_hash_tx_effect_tx_hash_fk" FOREIGN KEY ("tx_effect_hash") REFERENCES "public"."tx_effect"("tx_hash") ON DELETE cascade ON UPDATE no action; EXCEPTION @@ -333,12 +304,6 @@ EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "tx_effect_to_logs" ADD CONSTRAINT "tx_effect_to_logs_tx_effect_hash_tx_effect_tx_hash_fk" FOREIGN KEY ("tx_effect_hash") REFERENCES "public"."tx_effect"("tx_hash") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint DO $$ BEGIN ALTER TABLE "content_commitment" ADD CONSTRAINT "content_commitment_header_id_header_id_fk" FOREIGN KEY ("header_id") REFERENCES "public"."header"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION diff --git a/services/explorer-api/migrations/meta/0000_snapshot.json b/services/explorer-api/migrations/meta/0000_snapshot.json index 89bb67242..d45c16137 100644 --- a/services/explorer-api/migrations/meta/0000_snapshot.json +++ b/services/explorer-api/migrations/meta/0000_snapshot.json @@ -1,5 +1,5 @@ { - "id": "a83934b8-5dae-46a3-86fa-9ddc3e6fbd42", + "id": "09c080f8-cdb0-431b-93f8-9a3ef1bc32b8", "prevId": "00000000-0000-0000-0000-000000000000", "version": "7", "dialect": "postgresql", @@ -201,102 +201,6 @@ "compositePrimaryKeys": {}, "uniqueConstraints": {} }, - "public.function_logs": { - "name": "function_logs", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "index": { - "name": "index", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "tx_effect_to_logs_id": { - "name": "tx_effect_to_logs_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "function_logs_tx_effect_to_logs_id_tx_effect_to_logs_id_fk": { - "name": "function_logs_tx_effect_to_logs_id_tx_effect_to_logs_id_fk", - "tableFrom": "function_logs", - "tableTo": "tx_effect_to_logs", - "columnsFrom": ["tx_effect_to_logs_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "public.logs": { - "name": "logs", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "index": { - "name": "index", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "tx_effect_to_logs_id": { - "name": "tx_effect_to_logs_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "type": { - "name": "type", - "type": "varchar(20)", - "primaryKey": false, - "notNull": true - }, - "data": { - "name": "data", - "type": "bytea", - "primaryKey": false, - "notNull": true - }, - "contract_address": { - "name": "contract_address", - "type": "varchar(66)", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "logs_tx_effect_to_logs_id_tx_effect_to_logs_id_fk": { - "name": "logs_tx_effect_to_logs_id_tx_effect_to_logs_id_fk", - "tableFrom": "logs", - "tableTo": "tx_effect_to_logs", - "columnsFrom": ["tx_effect_to_logs_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, "public.public_data_write": { "name": "public_data_write", "schema": "", @@ -407,8 +311,8 @@ "primaryKey": false, "notNull": true }, - "unencrypted_logs_length": { - "name": "unencrypted_logs_length", + "contract_class_logs_length": { + "name": "contract_class_logs_length", "type": "bigint", "primaryKey": false, "notNull": true @@ -418,6 +322,18 @@ "type": "jsonb", "primaryKey": false, "notNull": true + }, + "public_logs": { + "name": "public_logs", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "contract_class_logs": { + "name": "contract_class_logs", + "type": "jsonb", + "primaryKey": false, + "notNull": true } }, "indexes": { @@ -451,39 +367,6 @@ "compositePrimaryKeys": {}, "uniqueConstraints": {} }, - "public.tx_effect_to_logs": { - "name": "tx_effect_to_logs", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "tx_effect_hash": { - "name": "tx_effect_hash", - "type": "varchar", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "tx_effect_to_logs_tx_effect_hash_tx_effect_tx_hash_fk": { - "name": "tx_effect_to_logs_tx_effect_hash_tx_effect_tx_hash_fk", - "tableFrom": "tx_effect_to_logs", - "tableTo": "tx_effect", - "columnsFrom": ["tx_effect_hash"], - "columnsTo": ["tx_hash"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, "public.content_commitment": { "name": "content_commitment", "schema": "", @@ -683,6 +566,12 @@ "type": "bigint", "primaryKey": false, "notNull": true + }, + "total_mana_used": { + "name": "total_mana_used", + "type": "bigint", + "primaryKey": false, + "notNull": true } }, "indexes": {}, diff --git a/services/explorer-api/migrations/meta/_journal.json b/services/explorer-api/migrations/meta/_journal.json index 6cce5094f..eb1028df6 100644 --- a/services/explorer-api/migrations/meta/_journal.json +++ b/services/explorer-api/migrations/meta/_journal.json @@ -5,8 +5,8 @@ { "idx": 0, "version": "7", - "when": 1737636499476, - "tag": "0000_concerned_frank_castle", + "when": 1738078932817, + "tag": "0000_public_firedrake", "breakpoints": true } ] diff --git a/services/explorer-api/package.json b/services/explorer-api/package.json index 09199600b..0bdd91230 100644 --- a/services/explorer-api/package.json +++ b/services/explorer-api/package.json @@ -6,9 +6,9 @@ "license": "Apache-2.0", "dependencies": { "@anatine/zod-openapi": "2.2.6", - "@aztec/aztec.js": "0.71.0", - "@aztec/circuits.js": "0.71.0", - "@aztec/protocol-contracts": "0.71.0", + "@aztec/aztec.js": "0.72.1", + "@aztec/circuits.js": "0.72.1", + "@aztec/protocol-contracts": "0.72.1", "@chicmoz-pkg/backend-utils": "workspace:^", "@chicmoz-pkg/error-middleware": "workspace:^", "@chicmoz-pkg/logger-server": "workspace:^", diff --git a/services/explorer-api/src/events/received/on-block/contracts.ts b/services/explorer-api/src/events/received/on-block/contracts.ts index b76321264..6ca5a130e 100644 --- a/services/explorer-api/src/events/received/on-block/contracts.ts +++ b/services/explorer-api/src/events/received/on-block/contracts.ts @@ -70,6 +70,8 @@ export const storeContracts = async (b: L2Block, blockHash: string) => { const privateLogs = b.body.txEffects.flatMap( (txEffect) => txEffect.privateLogs ); + // TODO: link contract instances & contract classes to blocks & txs: https://github.com/aztlan-labs/chicmoz/issues/285 + const contractInstances = privateLogs .filter((log) => ContractInstanceDeployedEvent.isContractInstanceDeployedEvent(log) diff --git a/services/explorer-api/src/svcs/database/controllers/l2TxEffect/get-tx-effect.ts b/services/explorer-api/src/svcs/database/controllers/l2TxEffect/get-tx-effect.ts index 832c6e6fe..dbbf5b33d 100644 --- a/services/explorer-api/src/svcs/database/controllers/l2TxEffect/get-tx-effect.ts +++ b/services/explorer-api/src/svcs/database/controllers/l2TxEffect/get-tx-effect.ts @@ -1,25 +1,20 @@ +import { getDb as db } from "@chicmoz-pkg/postgres-helper"; import { ChicmozL2TxEffect, ChicmozL2TxEffectDeluxe, HexString, - UnencryptedLogEntry, chicmozL2TxEffectDeluxeSchema, - unencryptedLogEntrySchema, } from "@chicmoz-pkg/types"; import { SQL, and, asc, eq, getTableColumns } from "drizzle-orm"; import { z } from "zod"; import { DB_MAX_TX_EFFECTS } from "../../../../environment.js"; -import { getDb as db } from "@chicmoz-pkg/postgres-helper"; import { body, - functionLogs, globalVariables, header, l2Block, - logs, publicDataWrite, txEffect, - txEffectToLogs, } from "../../../database/schema/l2block/index.js"; enum GetTypes { @@ -40,7 +35,7 @@ type GetTxEffectsByBlockHeight = { export const getTxEffectNestedByHash = async ( txEffectHash: string -): Promise> => { +): Promise> => { const publicDataWrites = await db() .select({ ...getTableColumns(publicDataWrite), @@ -50,50 +45,8 @@ export const getTxEffectNestedByHash = async ( .where(eq(publicDataWrite.txEffectHash, txEffectHash)) .orderBy(asc(publicDataWrite.index)) .execute(); - - const mixedLogs = await db() - .select({ - functionLogIndex: functionLogs.index, - ...getTableColumns(logs), - }) - .from(txEffectToLogs) - .innerJoin(logs, eq(txEffectToLogs.id, logs.txEffectToLogsId)) - .innerJoin( - functionLogs, - eq(txEffectToLogs.id, functionLogs.txEffectToLogsId) - ) - .where(eq(txEffectToLogs.txEffectHash, txEffectHash)) - .orderBy(asc(functionLogs.index), asc(logs.index)) - .execute(); - - const { highestIndexUnencryptedLogs } = mixedLogs.reduce( - (acc, { functionLogIndex }) => ({ - highestIndexUnencryptedLogs: Math.max( - acc.highestIndexUnencryptedLogs, - functionLogIndex - ), - }), - { - highestIndexUnencryptedLogs: -1, - } - ); - - const initialLogs = { - unencryptedLogs: { - functionLogs: new Array<{ logs: UnencryptedLogEntry[] }>( - highestIndexUnencryptedLogs + 1 - ).fill({ logs: [] }), - }, - }; - - for (const log of mixedLogs) { - const l = unencryptedLogEntrySchema.parse(log); - initialLogs.unencryptedLogs.functionLogs[log.functionLogIndex].logs.push(l); - } - return { publicDataWrites, - ...initialLogs, }; }; diff --git a/services/explorer-api/src/svcs/database/controllers/l2block/get-block.ts b/services/explorer-api/src/svcs/database/controllers/l2block/get-block.ts index cebdd7d13..329045064 100644 --- a/services/explorer-api/src/svcs/database/controllers/l2block/get-block.ts +++ b/services/explorer-api/src/svcs/database/controllers/l2block/get-block.ts @@ -85,6 +85,7 @@ const _getBlocks = async (args: GetBlocksArgs): Promise = archive: getTableColumnsWithoutId(archive), header_LastArchive: getTableColumnsWithoutId(lastArchive), header_TotalFees: header.totalFees, + header_TotalManaUsed: header.totalManaUsed, header_ContentCommitment: getTableColumnsWithoutId(contentCommitment), header_State_L1ToL2MessageTree: getTableColumnsWithoutId(l1ToL2MessageTree), header_State_Partial_NoteHashTree: getTableColumnsWithoutId(noteHashTree), @@ -159,6 +160,7 @@ const _getBlocks = async (args: GetBlocksArgs): Promise = header: { lastArchive: result.header_LastArchive, totalFees: result.header_TotalFees, + totalManaUsed: result.header_TotalManaUsed, contentCommitment: result.header_ContentCommitment, state: { l1ToL2MessageTree: result.header_State_L1ToL2MessageTree, diff --git a/services/explorer-api/src/svcs/database/controllers/l2block/store.ts b/services/explorer-api/src/svcs/database/controllers/l2block/store.ts index 71d19de0e..abf2fcdc1 100644 --- a/services/explorer-api/src/svcs/database/controllers/l2block/store.ts +++ b/services/explorer-api/src/svcs/database/controllers/l2block/store.ts @@ -1,8 +1,6 @@ -/* eslint-disable @typescript-eslint/no-unsafe-call */ import { HexString, type ChicmozL2Block, - type UnencryptedLogEntry, } from "@chicmoz-pkg/types"; import { v4 as uuidv4 } from "uuid"; import { getDb as db } from "@chicmoz-pkg/postgres-helper"; @@ -10,14 +8,12 @@ import { archive, body, contentCommitment, - functionLogs, gasFees, globalVariables, header, l1ToL2MessageTree, l2Block, lastArchive, - logs, noteHashTree, nullifierTree, partial, @@ -25,7 +21,6 @@ import { publicDataWrite, state, txEffect, - txEffectToLogs, } from "../../../database/schema/l2block/index.js"; export const store = async (block: ChicmozL2Block): Promise => { @@ -42,6 +37,7 @@ export const store = async (block: ChicmozL2Block): Promise => { id: headerId, blockHash: block.hash, totalFees: block.header.totalFees, + totalManaUsed: block.header.totalManaUsed, }); // Insert archive @@ -165,8 +161,10 @@ export const store = async (block: ChicmozL2Block): Promise => { noteHashes: txEff.noteHashes as HexString[], nullifiers: txEff.nullifiers as HexString[], l2ToL1Msgs: txEff.l2ToL1Msgs as HexString[], - unencryptedLogsLength: txEff.unencryptedLogsLength, + contractClassLogsLength: txEff.contractClassLogsLength, privateLogs: txEff.privateLogs, + publicLogs: txEff.publicLogs, + contractClassLogs: txEff.contractClassLogs, }); // Insert public data writes @@ -180,39 +178,6 @@ export const store = async (block: ChicmozL2Block): Promise => { value: pdw.value, }); } - - for (const [logType, fLogs] of Object.entries({ - unencrypted: txEff.unencryptedLogs.functionLogs, - })) { - const txEffectToLogsId = uuidv4(); - // Create junction entry for txEffectToLogs - await dbTx.insert(txEffectToLogs).values({ - id: txEffectToLogsId, - txEffectHash: txEff.txHash, - }); - for (const [functionLogIndex, functionLog] of Object.entries(fLogs)) { - // Insert logs - const functionLogId = uuidv4(); - await dbTx.insert(functionLogs).values({ - id: functionLogId, - index: Number(functionLogIndex), - txEffectToLogsId, - }); - for (const [index, log] of Object.entries( - functionLog.logs as Array - )) { - const logId = uuidv4(); - await dbTx.insert(logs).values({ - id: logId, - index: Number(index), - txEffectToLogsId, - type: logType, - data: log.data, - contractAddress: log.contractAddress, - }); - } - } - } } }); }; diff --git a/services/explorer-api/src/svcs/database/controllers/sign-of-life.ts b/services/explorer-api/src/svcs/database/controllers/sign-of-life.ts index 9feb29001..e122f04eb 100644 --- a/services/explorer-api/src/svcs/database/controllers/sign-of-life.ts +++ b/services/explorer-api/src/svcs/database/controllers/sign-of-life.ts @@ -1,14 +1,16 @@ -import { desc, eq, isNotNull, sql } from "drizzle-orm"; -import { NodePgDatabase } from "drizzle-orm/node-postgres"; import { getDb as db } from "@chicmoz-pkg/postgres-helper"; +import { desc, eq, sql } from "drizzle-orm"; +import { NodePgDatabase } from "drizzle-orm/node-postgres"; import { body, l2Block, - logs, txEffect, - txEffectToLogs, } from "../../database/schema/l2block/index.js"; -import { l2ContractInstanceDeployed, l2PrivateFunction, l2UnconstrainedFunction } from "../schema/index.js"; +import { + l2ContractInstanceDeployed, + l2PrivateFunction, + l2UnconstrainedFunction, +} from "../schema/index.js"; export const getABlock = async () => { const res = await db() @@ -72,26 +74,25 @@ export const getSomeTxEffectWithPrivateLogs = async () => { txHash: txEffect.txHash, }) .from(txEffect) - .where(isNotNull(txEffect.privateLogs)) + .where(sql`jsonb_array_length(${txEffect.privateLogs}) > 0`) .limit(10) .execute(); if (dbRes.length === 0) return null; return dbRes.map((row) => row.txHash); }; -export const getSomeTxEffectWithUnencryptedLogs = async () => { +export const getSomeTxEffectWithPublicLogs = async () => { const dbRes = await db() .select({ - hash: txEffectToLogs.txEffectHash, + hash: txEffect.txHash, }) - .from(logs) - .where(isNotNull(logs.contractAddress)) - .innerJoin(txEffectToLogs, eq(logs.txEffectToLogsId, txEffectToLogs.id)) + .from(txEffect) + .where(sql`jsonb_array_length(${txEffect.publicLogs}) > 0`) .limit(10) .execute(); if (dbRes.length === 0) return null; return dbRes.map((row) => row.hash); -} +}; export const getABlockWithContractInstances = async () => { const dbRes = await db() @@ -138,20 +139,21 @@ const getAL2PrivateFunction = async () => { .execute(); if (dbRes.length === 0) return null; return dbRes[0]; -} +}; const getAL2UnconstrainedFunction = async () => { const dbRes = await db() .select({ classId: l2UnconstrainedFunction.contractClassId, - functionSelector: l2UnconstrainedFunction.unconstrainedFunction_selector_value, + functionSelector: + l2UnconstrainedFunction.unconstrainedFunction_selector_value, }) .from(l2UnconstrainedFunction) .limit(1) .execute(); if (dbRes.length === 0) return null; - return dbRes[0] -} + return dbRes[0]; +}; export const getL2ContractFunctions = async () => { const [privateFunction, unconstrainedFunction] = await Promise.all([ diff --git a/services/explorer-api/src/svcs/database/schema/l2block/body.ts b/services/explorer-api/src/svcs/database/schema/l2block/body.ts index cf3cb2da4..f3e976b2d 100644 --- a/services/explorer-api/src/svcs/database/schema/l2block/body.ts +++ b/services/explorer-api/src/svcs/database/schema/l2block/body.ts @@ -9,12 +9,7 @@ import { uuid, varchar, } from "drizzle-orm/pg-core"; -import { - bufferType, - generateAztecAddressColumn, - generateFrColumn, - generateFrNumberColumn, -} from "../utils.js"; +import { generateFrColumn, generateFrNumberColumn } from "../utils.js"; import { l2Block } from "./root.js"; export const body = pgTable("body", { @@ -40,10 +35,12 @@ export const txEffect = pgTable( noteHashes: jsonb("note_hashes").notNull(), nullifiers: jsonb("nullifiers").notNull(), l2ToL1Msgs: jsonb("l2_to_l1_msgs").notNull().$type(), - unencryptedLogsLength: generateFrNumberColumn( - "unencrypted_logs_length" + contractClassLogsLength: generateFrNumberColumn( + "contract_class_logs_length" ).notNull(), privateLogs: jsonb("private_logs").notNull(), + publicLogs: jsonb("public_logs").notNull(), + contractClassLogs: jsonb("contract_class_logs").notNull(), }, (table) => ({ txHashIndex: index("tx_hash_index").on(table.txHash), @@ -59,30 +56,3 @@ export const publicDataWrite = pgTable("public_data_write", { leafSlot: generateFrColumn("leaf_slot").notNull(), value: generateFrColumn("value").notNull(), }); - -export const logs = pgTable("logs", { - id: uuid("id").primaryKey().defaultRandom(), - // TODO: move index to junction table - index: integer("index").notNull(), - txEffectToLogsId: uuid("tx_effect_to_logs_id") - .notNull() - .references(() => txEffectToLogs.id, { onDelete: "cascade" }), - type: varchar("type", { length: 20 }).notNull(), // unencrypted - data: bufferType("data").notNull(), - contractAddress: generateAztecAddressColumn("contract_address"), -}); - -export const functionLogs = pgTable("function_logs", { - id: uuid("id").primaryKey().defaultRandom(), - index: integer("index").notNull(), - txEffectToLogsId: uuid("tx_effect_to_logs_id") - .notNull() - .references(() => txEffectToLogs.id, { onDelete: "cascade" }), -}); - -export const txEffectToLogs = pgTable("tx_effect_to_logs", { - id: uuid("id").primaryKey().defaultRandom(), - txEffectHash: varchar("tx_effect_hash") - .notNull() - .references(() => txEffect.txHash, { onDelete: "cascade" }), -}); diff --git a/services/explorer-api/src/svcs/database/schema/l2block/header.ts b/services/explorer-api/src/svcs/database/schema/l2block/header.ts index de983b03b..dd502afaa 100644 --- a/services/explorer-api/src/svcs/database/schema/l2block/header.ts +++ b/services/explorer-api/src/svcs/database/schema/l2block/header.ts @@ -16,6 +16,7 @@ export const header = pgTable("header", { .$type() .references(() => l2Block.hash, { onDelete: "cascade" }), totalFees: bigint("total_fees", { mode: "bigint" }).notNull(), + totalManaUsed: bigint("total_mana_used", { mode: "bigint" }).notNull(), }); export const lastArchive = generateTreeTable( diff --git a/services/explorer-api/src/svcs/database/schema/l2block/relations.ts b/services/explorer-api/src/svcs/database/schema/l2block/relations.ts index 5e759038c..9dc386b75 100644 --- a/services/explorer-api/src/svcs/database/schema/l2block/relations.ts +++ b/services/explorer-api/src/svcs/database/schema/l2block/relations.ts @@ -2,11 +2,8 @@ import { relations } from "drizzle-orm"; import { body, - functionLogs, - logs, publicDataWrite, txEffect, - txEffectToLogs, } from "./body.js"; import { contentCommitment, @@ -143,8 +140,6 @@ export const bodyRelations = relations(body, ({ one, many }) => ({ export const txEffectRelations = relations(txEffect, ({ one, many }) => ({ bodyToTxEffects: one(body), publicDataWrite: many(publicDataWrite), - functionLogs: many(functionLogs), - txEffectToLogs: many(txEffectToLogs), })); export const publicDataWriteRelations = relations( @@ -153,26 +148,3 @@ export const publicDataWriteRelations = relations( txEffect: one(txEffect), }) ); - -export const logsRelations = relations(logs, ({ many }) => ({ - txEffectToLogs: many(txEffectToLogs), -})); - -export const functionLogsRelations = relations(functionLogs, ({ many }) => ({ - txEffectToLogs: many(txEffectToLogs), -})); - -export const txEffectToLogsRelations = relations(txEffectToLogs, ({ one }) => ({ - txEffect: one(txEffect, { - fields: [txEffectToLogs.txEffectHash], - references: [txEffect.txHash], - }), - log: one(logs, { - fields: [txEffectToLogs.id], - references: [logs.txEffectToLogsId], - }), - functionLog: one(functionLogs, { - fields: [txEffectToLogs.id], - references: [functionLogs.txEffectToLogsId], - }), -})); diff --git a/services/explorer-api/src/svcs/database/schema/l2tx/index.ts b/services/explorer-api/src/svcs/database/schema/l2tx/index.ts index 523e785d0..43ebded56 100644 --- a/services/explorer-api/src/svcs/database/schema/l2tx/index.ts +++ b/services/explorer-api/src/svcs/database/schema/l2tx/index.ts @@ -4,12 +4,4 @@ import { pgTable, timestamp, varchar } from "drizzle-orm/pg-core"; export const l2Tx = pgTable("tx", { hash: varchar("hash").notNull().$type().primaryKey(), birthTimestamp: timestamp("birth_timestamp").notNull().defaultNow(), - //data: text("data").notNull(), - //noteEncryptedLogs: text("note_encrypted_logs").notNull(), - //encryptedLogs: text("encrypted_logs").notNull(), - //unencryptedLogs: text("unencrypted_logs").notNull(), - //contractClassLogs: text("contract_class_logs").notNull(), - //clientIvcProof: text("client_ivc_proof").notNull(), - //enqueuedPublicFunctionCalls: jsonb("enqueued_public_function_calls").notNull(), - //publicTeardownFunctionCall: text("public_teardown_function_call").notNull(), }); diff --git a/services/explorer-api/src/svcs/http-server/routes/controllers/inofficial.ts b/services/explorer-api/src/svcs/http-server/routes/controllers/inofficial.ts index 9c5b21053..d87a7f88d 100644 --- a/services/explorer-api/src/svcs/http-server/routes/controllers/inofficial.ts +++ b/services/explorer-api/src/svcs/http-server/routes/controllers/inofficial.ts @@ -39,8 +39,8 @@ export const GET_ROUTES = asyncHandler(async (_req, res) => { await db.signOfLife.getL2ContractFunctions(); const somePrivateLogsTxEffects = await db.signOfLife.getSomeTxEffectWithPrivateLogs(); - const someUnencryptedLogsTxEffects = - await db.signOfLife.getSomeTxEffectWithUnencryptedLogs(); + const somePublicLogsTxEffects = + await db.signOfLife.getSomeTxEffectWithPublicLogs(); const r = [paths.latestHeight, paths.latestBlock, `${paths.blocks}?from=0`]; const searchRoutes = []; @@ -202,9 +202,9 @@ export const GET_ROUTES = asyncHandler(async (_req, res) => { ) .join("")} -

Unencrypted logs

+

Public logs

    - ${someUnencryptedLogsTxEffects + ${somePublicLogsTxEffects ?.map( (hash) => `
  • ${hash}
  • ` diff --git a/services/explorer-ui/src/components/blocks/blocks-schema.ts b/services/explorer-ui/src/components/blocks/blocks-schema.ts index e96cfbf65..b6377877e 100644 --- a/services/explorer-ui/src/components/blocks/blocks-schema.ts +++ b/services/explorer-ui/src/components/blocks/blocks-schema.ts @@ -7,5 +7,6 @@ export const blockSchema = z.object({ blockHash: z.string(), txEffectsLength: z.number(), totalFees: z.coerce.string(), + totalManaUsed: z.coerce.string(), timestamp: z.number(), }); diff --git a/services/explorer-ui/src/pages/contract-class-details/constants.ts b/services/explorer-ui/src/pages/contract-class-details/constants.ts index d8c122f23..0d039dd3d 100644 --- a/services/explorer-ui/src/pages/contract-class-details/constants.ts +++ b/services/explorer-ui/src/pages/contract-class-details/constants.ts @@ -4,13 +4,15 @@ export type tabId = | "contractVersions" | "contractInstances" | "privateFunctions" - | "unconstrainedFunctions"; + | "unconstrainedFunctions" + | "artifactJson"; export const tabIds = [ "contractVersions", "contractInstances", "privateFunctions", "unconstrainedFunctions", + "artifactJson", ] as const; export const tabIdSchema = z.enum(tabIds); @@ -27,4 +29,5 @@ export const contractClassTabs: Tab[] = [ { id: "contractInstances", label: "Instances" }, { id: "privateFunctions", label: "Private functions" }, { id: "unconstrainedFunctions", label: "Unconstrained functions" }, + { id: "artifactJson", label: "Artifact JSON" }, ]; diff --git a/services/explorer-ui/src/pages/contract-class-details/index.tsx b/services/explorer-ui/src/pages/contract-class-details/index.tsx index d05768b17..ff616d517 100644 --- a/services/explorer-ui/src/pages/contract-class-details/index.tsx +++ b/services/explorer-ui/src/pages/contract-class-details/index.tsx @@ -42,6 +42,9 @@ export const ContractClassDetails: FC = () => { const contractClasses = mapContractClasses(classesData); const contractInstances = mapContractInstances(instancesData); + const selectedVersion = classesData?.find( + (contract) => contract.version === Number(version) + ); const isOptionAvailable = { contractVersions: !!contractClasses && !!contractClasses.length, contractInstances: !!contractInstances && !!contractInstances.length, @@ -55,12 +58,10 @@ export const ContractClassDetails: FC = () => { !contractClassUnconstrainedFunctionsHookRes.error && !!contractClassUnconstrainedFunctionsHookRes.data && !!contractClassUnconstrainedFunctionsHookRes.data.length, + artifactJson: !!selectedVersion && !!selectedVersion.artifactJson, }; if (!id) return
    No classId
    ; - const selectedVersion = classesData?.find( - (contract) => contract.version === Number(version) - ); if (!selectedVersion) return
    No data
    ; return ( @@ -226,9 +227,18 @@ export const ContractClassDetails: FC = () => { )} )} - { - // TODO: add artifactJson - } + {selectedTab === "artifactJson" && selectedVersion.artifactJson && ( +
    +

    Artifact JSON

    +
    +                {JSON.stringify(
    +                  JSON.parse(selectedVersion.artifactJson),
    +                  null,
    +                  2
    +                )}
    +              
    +
    + )} diff --git a/services/explorer-ui/src/pages/contract/util.ts b/services/explorer-ui/src/pages/contract/util.ts index f34db6181..0ceb64d18 100644 --- a/services/explorer-ui/src/pages/contract/util.ts +++ b/services/explorer-ui/src/pages/contract/util.ts @@ -1,12 +1,12 @@ import { - ChicmozL2ContractClassRegisteredEvent, - ChicmozL2ContractInstanceDeluxe, + type ChicmozL2ContractClassRegisteredEvent, + type ChicmozL2ContractInstanceDeluxe, } from "@chicmoz-pkg/types"; import { contractClassSchema } from "~/components/contracts/classes/schema"; import { contractInstanceSchema } from "~/components/contracts/instances/schema"; export const mapContractClasses = ( - classesData?: ChicmozL2ContractClassRegisteredEvent[], + classesData?: ChicmozL2ContractClassRegisteredEvent[] ) => { if (!classesData) return undefined; return classesData.map((contractClass) => @@ -16,12 +16,13 @@ export const mapContractClasses = ( version: contractClass.version, artifactHash: contractClass.artifactHash, privateFunctionsRoot: contractClass.privateFunctionsRoot, - }), + artifactJson: contractClass.artifactJson, + }) ); }; export const mapContractInstances = ( - instancesData?: ChicmozL2ContractInstanceDeluxe[], + instancesData?: ChicmozL2ContractInstanceDeluxe[] ) => { if (!instancesData) return undefined; return instancesData.map((contractInstance) => @@ -32,6 +33,6 @@ export const mapContractInstances = ( version: contractInstance.version, contractClassId: contractInstance.contractClassId, deployer: contractInstance.deployer, - }), + }) ); }; diff --git a/services/explorer-ui/src/pages/dev.tsx b/services/explorer-ui/src/pages/dev.tsx index 0fba9fc07..068a5a4cf 100644 --- a/services/explorer-ui/src/pages/dev.tsx +++ b/services/explorer-ui/src/pages/dev.tsx @@ -44,7 +44,7 @@ export const DevPage: FC = () => {

    Misc

    -          

    {`Aztec.js version 0.71.0`}

    +

    {`Aztec.js version 0.72.1`}

    {`Explorer version ${VERSION_STRING}`}

    {`API URL ${API_URL}`}

    {`WS URL ${WS_URL}`}

    diff --git a/services/explorer-ui/src/pages/tx-effect-details/constants.ts b/services/explorer-ui/src/pages/tx-effect-details/constants.ts index 8a51592f2..7c860cab6 100644 --- a/services/explorer-ui/src/pages/tx-effect-details/constants.ts +++ b/services/explorer-ui/src/pages/tx-effect-details/constants.ts @@ -2,7 +2,7 @@ import { z } from "zod"; export type tabId = | "privateLogs" - | "unencryptedLogs" + | "publicLogs" | "nullifiers" | "noteHashes" | "l2ToL1Msgs" @@ -11,7 +11,7 @@ export type tabId = // Define the tab IDs array export const tabIds = [ "privateLogs", - "unencryptedLogs", + "publicLogs", "nullifiers", "noteHashes", "l2ToL1Msgs", @@ -29,7 +29,7 @@ export type Tab = z.infer; export const txEffectTabs: Tab[] = [ { id: "privateLogs", label: "Private logs" }, - { id: "unencryptedLogs", label: "Unencrypted logs" }, + { id: "publicLogs", label: "Public logs" }, { id: "nullifiers", label: "Nullifiers" }, { id: "noteHashes", label: "Note hashes" }, { id: "l2ToL1Msgs", label: "L2 to L1 messages" }, diff --git a/services/explorer-ui/src/pages/tx-effect-details/index.tsx b/services/explorer-ui/src/pages/tx-effect-details/index.tsx index b0e9d85de..b73eb9325 100644 --- a/services/explorer-ui/src/pages/tx-effect-details/index.tsx +++ b/services/explorer-ui/src/pages/tx-effect-details/index.tsx @@ -3,27 +3,25 @@ import { useState, type FC } from "react"; import { KeyValueDisplay } from "~/components/info-display/key-value-display"; import { OptionButtons } from "~/components/option-buttons"; import { useGetTxEffectByHash, useSubTitle } from "~/hooks"; +import { routes } from "~/routes/__root"; import { txEffectTabs, type TabId } from "./constants"; import { getTxEffectData, mapTxEffectsData } from "./utils"; -const naiveDecode = (data: Buffer): string => { - // TODO +const naiveDecode = (data: string[]): string => { let counterZero = 0; let counterAbove128 = 0; - const res = - data - .toString("hex") - .match(/.{1,64}/g) - ?.map((hex) => parseInt(hex, 16)) - .map((charCode): string => { - if (charCode === 0) counterZero++; - if (charCode > 128) counterAbove128++; - const char = String.fromCharCode(charCode); - return char; - }) - .join("") ?? ""; - const isProbablyADecodedString = counterZero === 0 && counterAbove128 === 0; - return isProbablyADecodedString ? res : data.toString("hex"); + const charCodes: number[] = data + ?.map((hex) => parseInt(hex, 16)) + .map((charCode) => { + if (charCode === 0) counterZero++; + if (charCode > 128) counterAbove128++; + return charCode; + }); + const isNoWeirdChars = counterZero + counterAbove128 === 0; + const isProbablyAReadableString = + isNoWeirdChars || data.length - charCodes.indexOf(0) === counterZero; + const res = charCodes.map((char) => String.fromCharCode(char)).join(""); + return isProbablyAReadableString ? res : data.join("\n"); }; export const TxEffectDetails: FC = () => { @@ -64,11 +62,6 @@ export const TxEffectDetails: FC = () => { {selectedTab === "privateLogs" && (
    {txEffects.privateLogs.map((log, index) => { - //const entries = log.map((logNbr, i) => ({ - // label: `Log ${i + 1}`, - // value: logNbr.toString(), - // isClickable: false, - //})); const entries = [ { label: "data", @@ -85,37 +78,61 @@ export const TxEffectDetails: FC = () => { })}
    )} - {selectedTab === "unencryptedLogs" && ( + {selectedTab === "publicLogs" && (
    - {txEffects.unencryptedLogs.functionLogs.map( - (unencrypted, index) => { - const entries = unencrypted.logs.map((unEncLog) => { - return [ + { + txEffects.publicLogs.map( + ([contractAddress, ...logData], index) => { + const entries = [ { label: "data", - value: naiveDecode(unEncLog.data), + value: naiveDecode(logData), isClickable: false, }, { label: "Contract Address", - value: (unEncLog as { contractAddress: string }) - .contractAddress, + value: contractAddress, + link: `${routes.contracts.route}/${routes.contracts.children.instances.route}/${contractAddress}`, isClickable: true, }, ]; - }); - // Flatten the nested arrays - const flattenedEntries = entries.flat(); - - // Render KeyValueDisplay with the flattened entries - return ( -
    -

    Log {index + 1}

    - -
    - ); - } - )} + return ( +
    +

    Log {index + 1}

    + +
    + ); + } + ) + // TODO: decode logs (old decode below) + // txEffects.unencryptedLogs.functionLogs.map( + // (unencrypted, index) => { + // const entries = unencrypted.logs.map((unEncLog) => { + // return [ + // { + // label: "data", + // value: naiveDecode(unEncLog.data), + // isClickable: false, + // }, + // { + // label: "Contract Address", + // value: (unEncLog as { contractAddress: string }) + // .contractAddress, + // isClickable: true, + // }, + // ]; + // }); + // // Flatten the nested arrays + // const flattenedEntries = entries.flat(); + // // Render KeyValueDisplay with the flattened entries + // return ( + //
    + //

    Log {index + 1}

    + // + //
    + // ); + // } + }
    )} {selectedTab === "nullifiers" && ( diff --git a/services/explorer-ui/src/pages/tx-effect-details/utils.ts b/services/explorer-ui/src/pages/tx-effect-details/utils.ts index 29b330d30..5f1916235 100644 --- a/services/explorer-ui/src/pages/tx-effect-details/utils.ts +++ b/services/explorer-ui/src/pages/tx-effect-details/utils.ts @@ -46,9 +46,7 @@ export const mapTxEffectsData = ( ): Record => { return { privateLogs: !!data?.privateLogs?.length, - unencryptedLogs: !!data?.unencryptedLogs?.functionLogs?.filter( - (log) => log.logs.length > 0 - ).length, + publicLogs: !!data?.publicLogs?.length, nullifiers: !!data?.nullifiers?.length, noteHashes: !!data?.noteHashes?.length, l2ToL1Msgs: !!data?.l2ToL1Msgs?.length, diff --git a/yarn.lock b/yarn.lock index a461fc48c..d485c1ba8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -41,43 +41,43 @@ __metadata: languageName: node linkType: hard -"@aztec/accounts@npm:0.71.0": - version: 0.71.0 - resolution: "@aztec/accounts@npm:0.71.0" - dependencies: - "@aztec/aztec.js": "npm:0.71.0" - "@aztec/circuit-types": "npm:0.71.0" - "@aztec/circuits.js": "npm:0.71.0" - "@aztec/entrypoints": "npm:0.71.0" - "@aztec/ethereum": "npm:0.71.0" - "@aztec/foundation": "npm:0.71.0" - "@aztec/types": "npm:0.71.0" +"@aztec/accounts@npm:0.72.1": + version: 0.72.1 + resolution: "@aztec/accounts@npm:0.72.1" + dependencies: + "@aztec/aztec.js": "npm:0.72.1" + "@aztec/circuit-types": "npm:0.72.1" + "@aztec/circuits.js": "npm:0.72.1" + "@aztec/entrypoints": "npm:0.72.1" + "@aztec/ethereum": "npm:0.72.1" + "@aztec/foundation": "npm:0.72.1" + "@aztec/types": "npm:0.72.1" tslib: "npm:^2.4.0" - checksum: 9bc3c922eb7960184e18b292ea4b21802f8b27c95b719cbd51df5cbb6c22f2b93746ab3c0b98138483ba796036658e54851d6a0fb8753fcfed27148b1974dcff + checksum: af1c3810bc939d81567967158de02614f880fff2300cdca1d48e1f0710b0ab32f67b76513229763d729b0d5dba11f1b36d65dbc6f3c7086ef35edb25fab1495f languageName: node linkType: hard -"@aztec/aztec.js@npm:0.71.0": - version: 0.71.0 - resolution: "@aztec/aztec.js@npm:0.71.0" +"@aztec/aztec.js@npm:0.72.1": + version: 0.72.1 + resolution: "@aztec/aztec.js@npm:0.72.1" dependencies: - "@aztec/circuit-types": "npm:0.71.0" - "@aztec/circuits.js": "npm:0.71.0" - "@aztec/ethereum": "npm:0.71.0" - "@aztec/foundation": "npm:0.71.0" - "@aztec/l1-artifacts": "npm:0.71.0" - "@aztec/protocol-contracts": "npm:0.71.0" - "@aztec/types": "npm:0.71.0" + "@aztec/circuit-types": "npm:0.72.1" + "@aztec/circuits.js": "npm:0.72.1" + "@aztec/ethereum": "npm:0.72.1" + "@aztec/foundation": "npm:0.72.1" + "@aztec/l1-artifacts": "npm:0.72.1" + "@aztec/protocol-contracts": "npm:0.72.1" + "@aztec/types": "npm:0.72.1" axios: "npm:^1.7.2" tslib: "npm:^2.4.0" - viem: "npm:^2.7.15" - checksum: 3774e216282763105a5c798d9313d4db931ee5b8c5cea00125c5da3208de3dfeeb46096b3427fd1ff32b46096a467b235f2766979767c2abe8092836a07650f5 + viem: "npm:2.22.8" + checksum: d32beda00bb1568879f30a1d213c6bb963da560f9f788eaabe1ad2616301b2528b32199b1340054171e1460eca2af55c3f81e931ee8e1c8faabf970653aa19bc languageName: node linkType: hard -"@aztec/bb.js@npm:0.71.0": - version: 0.71.0 - resolution: "@aztec/bb.js@npm:0.71.0" +"@aztec/bb.js@npm:0.72.1": + version: 0.72.1 + resolution: "@aztec/bb.js@npm:0.72.1" dependencies: comlink: "npm:^4.4.1" commander: "npm:^12.1.0" @@ -87,78 +87,77 @@ __metadata: tslib: "npm:^2.4.0" bin: bb.js: dest/node/main.js - checksum: cda7fee25874a1f6b71e1f25befbf11ce60d92511930fd7d3514859e4a998c606886bbb03597693715c38c801e72472bf175ae86172860f01fb4023c3e6315e1 + checksum: 33895489666d2e58e333397cffdb76940691217f96a229708410f026c3225b87566a0639c423fa2a44a0addcbebe48accaa3c4ee010a92fc931b611e8ba4a444 languageName: node linkType: hard -"@aztec/circuit-types@npm:0.71.0": - version: 0.71.0 - resolution: "@aztec/circuit-types@npm:0.71.0" +"@aztec/circuit-types@npm:0.72.1": + version: 0.72.1 + resolution: "@aztec/circuit-types@npm:0.72.1" dependencies: - "@aztec/circuits.js": "npm:0.71.0" - "@aztec/ethereum": "npm:0.71.0" - "@aztec/foundation": "npm:0.71.0" - "@aztec/types": "npm:0.71.0" + "@aztec/circuits.js": "npm:0.72.1" + "@aztec/ethereum": "npm:0.72.1" + "@aztec/foundation": "npm:0.72.1" + "@aztec/types": "npm:0.72.1" browserify-cipher: "npm:^1.0.1" lodash.clonedeep: "npm:^4.5.0" lodash.isequal: "npm:^4.5.0" lodash.times: "npm:^4.3.2" tslib: "npm:^2.5.0" zod: "npm:^3.23.8" - checksum: 85f23e8a9348539107d2f890bf325487bc36411488ffc6279af428ffd53df9cf5ab32fe6dbdcf5484b80e76135fca9a2d62e1253c2c8611de7b0d62ae2667195 + checksum: 4084eb40a64d04bff666e032cea44e06a4ca9939ec82f101c7e76bc064465e7c4cce6ba0256684ef6f85ce254dd21c6bd7cfdf1e97059a9456b0545b517bef31 languageName: node linkType: hard -"@aztec/circuits.js@npm:0.71.0": - version: 0.71.0 - resolution: "@aztec/circuits.js@npm:0.71.0" +"@aztec/circuits.js@npm:0.72.1": + version: 0.72.1 + resolution: "@aztec/circuits.js@npm:0.72.1" dependencies: - "@aztec/bb.js": "npm:0.71.0" - "@aztec/ethereum": "npm:0.71.0" - "@aztec/foundation": "npm:0.71.0" - "@aztec/types": "npm:0.71.0" - eslint: "npm:^8.35.0" + "@aztec/bb.js": "npm:0.72.1" + "@aztec/ethereum": "npm:0.72.1" + "@aztec/foundation": "npm:0.72.1" + "@aztec/types": "npm:0.72.1" msgpackr: "npm:^1.11.2" tslib: "npm:^2.4.0" zod: "npm:^3.23.8" - checksum: 0c872fe7c30aee449a9b303a739efab19d11e21b087d00fa3c77adea6b8c615924cfe425b62ec0d993358a0b7888a7b1d30885d4d5ec6c16c4e58e2046b02353 + checksum: 6790054d22e97034e7491a6dcda552d3e0303a5d503ac6fbfb15484a1cba6e87e260a3aa3d0fa5751ddd5d30a74cce636270d48ba2322ab871471733b7b20711 languageName: node linkType: hard -"@aztec/entrypoints@npm:0.71.0": - version: 0.71.0 - resolution: "@aztec/entrypoints@npm:0.71.0" +"@aztec/entrypoints@npm:0.72.1": + version: 0.72.1 + resolution: "@aztec/entrypoints@npm:0.72.1" dependencies: - "@aztec/aztec.js": "npm:0.71.0" - "@aztec/circuit-types": "npm:0.71.0" - "@aztec/circuits.js": "npm:0.71.0" - "@aztec/foundation": "npm:0.71.0" - "@aztec/protocol-contracts": "npm:0.71.0" + "@aztec/aztec.js": "npm:0.72.1" + "@aztec/circuit-types": "npm:0.72.1" + "@aztec/circuits.js": "npm:0.72.1" + "@aztec/foundation": "npm:0.72.1" + "@aztec/protocol-contracts": "npm:0.72.1" tslib: "npm:^2.4.0" - checksum: 21eb45782ed9f95b04bb7cb87fecbca7ffcc046636ef09c9672d83092b86d16cb273f83f60eba3962adc9c05377f839382f5959a5999ec93026a7a4987cb758d + checksum: 82665aa909819e90adfbbf8b32ce258f0bb7797b247c6e01217be5c005db49953caa06b67a5ae2d9b0f865883a801d14cc0159413b424504c57ac33e406a9dd8 languageName: node linkType: hard -"@aztec/ethereum@npm:0.71.0": - version: 0.71.0 - resolution: "@aztec/ethereum@npm:0.71.0" +"@aztec/ethereum@npm:0.72.1": + version: 0.72.1 + resolution: "@aztec/ethereum@npm:0.72.1" dependencies: - "@aztec/foundation": "npm:0.71.0" - "@aztec/l1-artifacts": "npm:0.71.0" + "@aztec/foundation": "npm:0.72.1" + "@aztec/l1-artifacts": "npm:0.72.1" "@viem/anvil": "npm:^0.0.10" dotenv: "npm:^16.0.3" tslib: "npm:^2.4.0" - viem: "npm:^2.7.15" + viem: "npm:2.22.8" zod: "npm:^3.23.8" - checksum: 0decdbe79fcbf75caeea932a9747c1394e2e705155a07be30485e111a8e5d5c7feaa5888e360c64606a713c40a97cafea26f29f5de3e3cb050efacf4e1e74529 + checksum: ef72694272c7554fd6a6558eca9bef29a6753491f69ba97ec54759e5c780d027694b32e7ed6c1f47b83af94e6f469aff366169dcefe1260ae5962cb8e40a9e97 languageName: node linkType: hard -"@aztec/foundation@npm:0.71.0": - version: 0.71.0 - resolution: "@aztec/foundation@npm:0.71.0" +"@aztec/foundation@npm:0.72.1": + version: 0.72.1 + resolution: "@aztec/foundation@npm:0.72.1" dependencies: - "@aztec/bb.js": "npm:0.71.0" + "@aztec/bb.js": "npm:0.72.1" "@koa/cors": "npm:^5.0.0" "@noble/curves": "npm:^1.2.0" bn.js: "npm:^5.2.1" @@ -182,50 +181,50 @@ __metadata: pino-pretty: "npm:^13.0.0" sha3: "npm:^2.1.4" zod: "npm:^3.23.8" - checksum: bbeba07375f2d1eabec04a0a01be692be562b9221def0cbec0144f9781b5fa893ab077e42249204b9c4500e78681d07081ee781365d36986096d2f202c1e4396 + checksum: 2cf7f417205a141d44427ba5ac71ea0404491d05f1baa2cd2bd8c112be368c60f410ea0b94698aea24475f3302466b99f553f741ea89af913606005b4604066b languageName: node linkType: hard -"@aztec/l1-artifacts@npm:0.71.0": - version: 0.71.0 - resolution: "@aztec/l1-artifacts@npm:0.71.0" +"@aztec/l1-artifacts@npm:0.72.1": + version: 0.72.1 + resolution: "@aztec/l1-artifacts@npm:0.72.1" dependencies: tslib: "npm:^2.4.0" - checksum: 8c79d08e25b20cc3136a9fd567828d5f3227cf9ca0da0ee2f8511bb149b3c15fdd4e74c1065aa78bc2dc88eb89f0f6549c05eb60c355650c48c69a7959216f45 + checksum: 4c517b50c720b59e23daabb8caf0a14c9eead484fb99b8d7f73248187577668a88d69890eee5ab421574c18ba18dc76aa7ad9fef5d7b52a035ae8155da0759a7 languageName: node linkType: hard -"@aztec/noir-contracts.js@npm:0.71.0": - version: 0.71.0 - resolution: "@aztec/noir-contracts.js@npm:0.71.0" +"@aztec/noir-contracts.js@npm:0.72.1": + version: 0.72.1 + resolution: "@aztec/noir-contracts.js@npm:0.72.1" dependencies: - "@aztec/aztec.js": "npm:0.71.0" + "@aztec/aztec.js": "npm:0.72.1" tslib: "npm:^2.4.0" - checksum: c044b56526f23e79d413509d4163dcd021190d3ef5dfb76fcd51d4b5111fa3e548d3cc7bb261a1be7592c91346f0232b572a9d68e01aa4be621418872ffac8b2 + checksum: 1677ca3ed0369dfce151c3fe5f9b39a2e88981dc601e9de970f5c5b4a45c366620f3059a047bca083441e3c68110213a979b0504575e9877871e506c742146c7 languageName: node linkType: hard -"@aztec/protocol-contracts@npm:0.71.0": - version: 0.71.0 - resolution: "@aztec/protocol-contracts@npm:0.71.0" +"@aztec/protocol-contracts@npm:0.72.1": + version: 0.72.1 + resolution: "@aztec/protocol-contracts@npm:0.72.1" dependencies: - "@aztec/circuits.js": "npm:0.71.0" - "@aztec/foundation": "npm:0.71.0" - "@aztec/types": "npm:0.71.0" + "@aztec/circuits.js": "npm:0.72.1" + "@aztec/foundation": "npm:0.72.1" + "@aztec/types": "npm:0.72.1" lodash.chunk: "npm:^4.2.0" lodash.omit: "npm:^4.5.0" tslib: "npm:^2.4.0" - checksum: b62f625227a84e3b37fa88a00ea05c9de8f09a0c7c2ff2434971d886165b5eacb81ad8a4de69b7673e95c3efbcc1a8499310eb48e02e12c3d82aa351189dafd3 + checksum: 098e374337b5e4890710c7982aa9a5ccd7a5064cb7ee24530eebed87b3f3dfeab9791234a9fa68e5980ca1f8867470135e63f6f823de1682275dad74b0e09464 languageName: node linkType: hard -"@aztec/types@npm:0.71.0": - version: 0.71.0 - resolution: "@aztec/types@npm:0.71.0" +"@aztec/types@npm:0.72.1": + version: 0.72.1 + resolution: "@aztec/types@npm:0.72.1" dependencies: - "@aztec/ethereum": "npm:0.71.0" - "@aztec/foundation": "npm:0.71.0" - checksum: 4fb8d61e84f7ce19674b298d6bae1da1688b45d459d4e7eb7e602e8786f705f807344931bbc1d970b2627b19a09309a99f3fc5903f2ecc962b049ee1fa381af4 + "@aztec/ethereum": "npm:0.72.1" + "@aztec/foundation": "npm:0.72.1" + checksum: 509680df251788733ff949b214d658d653ba2a0850810480bfe78a302ddb938a6e7a9dfdbfa194002b2b28dd590a875c4ac25b91cceffbbf911ddd8e0034ceab languageName: node linkType: hard @@ -773,7 +772,7 @@ __metadata: version: 0.0.0-use.local resolution: "@chicmoz-pkg/backend-utils@workspace:packages/backend-utils" dependencies: - "@aztec/aztec.js": "npm:0.71.0" + "@aztec/aztec.js": "npm:0.72.1" "@chicmoz-pkg/types": "workspace:^" "@types/pg": "npm:8.11.8" "@typescript-eslint/eslint-plugin": "npm:6.11.0" @@ -859,7 +858,7 @@ __metadata: version: 0.0.0-use.local resolution: "@chicmoz-pkg/message-registry@workspace:packages/message-registry" dependencies: - "@aztec/aztec.js": "npm:0.71.0" + "@aztec/aztec.js": "npm:0.72.1" "@chicmoz-pkg/types": "workspace:^" "@typescript-eslint/eslint-plugin": "npm:6.11.0" "@typescript-eslint/parser": "npm:6.11.0" @@ -916,9 +915,6 @@ __metadata: version: 0.0.0-use.local resolution: "@chicmoz-pkg/types@workspace:packages/types" dependencies: - "@aztec/aztec.js": "npm:0.71.0" - "@aztec/circuits.js": "npm:0.71.0" - "@aztec/ethereum": "npm:0.71.0" "@typescript-eslint/eslint-plugin": "npm:6.11.0" "@typescript-eslint/parser": "npm:6.11.0" eslint: "npm:8.53.0" @@ -977,8 +973,8 @@ __metadata: version: 0.0.0-use.local resolution: "@chicmoz/aztec-listener@workspace:services/aztec-listener" dependencies: - "@aztec/aztec.js": "npm:0.71.0" - "@aztec/circuits.js": "npm:0.71.0" + "@aztec/aztec.js": "npm:0.72.1" + "@aztec/circuits.js": "npm:0.72.1" "@chicmoz-pkg/backend-utils": "workspace:^" "@chicmoz-pkg/logger-server": "workspace:^" "@chicmoz-pkg/message-bus": "workspace:^" @@ -1032,8 +1028,8 @@ __metadata: version: 0.0.0-use.local resolution: "@chicmoz/ethereum-listener@workspace:services/ethereum-listener" dependencies: - "@aztec/aztec.js": "npm:0.71.0" - "@aztec/l1-artifacts": "npm:0.71.0" + "@aztec/aztec.js": "npm:0.72.1" + "@aztec/l1-artifacts": "npm:0.72.1" "@chicmoz-pkg/logger-server": "workspace:^" "@chicmoz-pkg/message-bus": "workspace:^" "@chicmoz-pkg/message-registry": "workspace:^" @@ -1056,10 +1052,10 @@ __metadata: version: 0.0.0-use.local resolution: "@chicmoz/event-cannon@workspace:services/event-cannon" dependencies: - "@aztec/accounts": "npm:0.71.0" - "@aztec/aztec.js": "npm:0.71.0" - "@aztec/l1-artifacts": "npm:0.71.0" - "@aztec/noir-contracts.js": "npm:0.71.0" + "@aztec/accounts": "npm:0.72.1" + "@aztec/aztec.js": "npm:0.72.1" + "@aztec/l1-artifacts": "npm:0.72.1" + "@aztec/noir-contracts.js": "npm:0.72.1" "@chicmoz-pkg/logger-server": "workspace:^" "@types/node": "npm:20.5.0" "@typescript-eslint/eslint-plugin": "npm:6.11.0" @@ -1079,9 +1075,9 @@ __metadata: resolution: "@chicmoz/explorer-api@workspace:services/explorer-api" dependencies: "@anatine/zod-openapi": "npm:2.2.6" - "@aztec/aztec.js": "npm:0.71.0" - "@aztec/circuits.js": "npm:0.71.0" - "@aztec/protocol-contracts": "npm:0.71.0" + "@aztec/aztec.js": "npm:0.72.1" + "@aztec/circuits.js": "npm:0.72.1" + "@aztec/protocol-contracts": "npm:0.72.1" "@chicmoz-pkg/backend-utils": "workspace:^" "@chicmoz-pkg/error-middleware": "workspace:^" "@chicmoz-pkg/logger-server": "workspace:^" @@ -7758,7 +7754,7 @@ __metadata: languageName: node linkType: hard -"eslint@npm:8.57.0, eslint@npm:^8.35.0": +"eslint@npm:8.57.0": version: 8.57.0 resolution: "eslint@npm:8.57.0" dependencies: