From 4e4a34c4c0209618a427bee15fff4da35e2d93b2 Mon Sep 17 00:00:00 2001 From: filip Date: Mon, 6 Jan 2025 14:04:47 +0100 Subject: [PATCH 01/11] done --- ...affold.only_websocket-event-publisher.yaml | 16 + packages/backend-utils/src/parse-block.ts | 2 - packages/types/src/api/index.ts | 2 +- packages/types/src/aztec/l2Block.ts | 2 +- packages/types/src/aztec/l2TxEffect.ts | 3 - packages/types/src/aztec/special.ts | 2 +- packages/types/src/general.ts | 23 +- .../SimpleLogging/Nargo.toml | 2 +- .../target/simple_logging-SimpleLogging.json | 398 ++++++++++-------- .../simple_logging-SimpleLogging.json.bak | 2 +- ...lack_queen.sql => 0000_bored_mandrill.sql} | 11 +- .../migrations/meta/0000_snapshot.json | 30 +- .../migrations/meta/_journal.json | 4 +- .../src/database/controllers/l2/search.ts | 6 +- .../controllers/l2TxEffect/get-tx-effect.ts | 8 +- .../database/controllers/l2block/get-block.ts | 2 +- .../src/database/controllers/l2block/store.ts | 7 +- .../src/database/controllers/sign-of-life.ts | 10 +- .../src/database/schema/l2block/body.ts | 7 +- .../src/database/schema/l2block/header.ts | 2 +- .../src/database/schema/l2block/relations.ts | 2 +- .../explorer-ui/src/components/header.tsx | 2 +- .../tx-effects/tx-effects-columns.tsx | 30 +- .../tx-effects/tx-effects-schema.ts | 2 - services/explorer-ui/src/hooks/websocket.ts | 8 +- .../explorer-ui/src/pages/landing/index.tsx | 3 +- .../src/pages/tx-effect-details/utils.ts | 6 +- .../src/ws-server/index.ts | 17 +- 28 files changed, 326 insertions(+), 283 deletions(-) create mode 100644 k8s/local/skaffold.only_websocket-event-publisher.yaml rename services/explorer-api/migrations/{0000_tearful_black_queen.sql => 0000_bored_mandrill.sql} (97%) diff --git a/k8s/local/skaffold.only_websocket-event-publisher.yaml b/k8s/local/skaffold.only_websocket-event-publisher.yaml new file mode 100644 index 00000000..3b4174af --- /dev/null +++ b/k8s/local/skaffold.only_websocket-event-publisher.yaml @@ -0,0 +1,16 @@ +apiVersion: skaffold/v4beta6 +kind: Config +metadata: + name: chicmoz +requires: + - path: ./chicmoz-base-image.yaml + - path: ./websocket-event-publisher/image.yaml +deploy: + kubectl: + flags: + apply: ["--force"] +manifests: + rawYaml: + - k8s/local/websocket-event-publisher/ingress.yaml + - k8s/local/websocket-event-publisher/deployment.yaml + - k8s/local/websocket-event-publisher/service.yaml diff --git a/packages/backend-utils/src/parse-block.ts b/packages/backend-utils/src/parse-block.ts index 53f84170..fbc91e56 100644 --- a/packages/backend-utils/src/parse-block.ts +++ b/packages/backend-utils/src/parse-block.ts @@ -7,7 +7,6 @@ const getTxEffectWithHashes = (txEffects: L2Block["body"]["txEffects"]) => { ...txEffect, unencryptedLogslength: txEffect.unencryptedLogsLength.toNumber(), privateLogs: txEffect.privateLogs.map((log) => log.toFields()), - hash: txEffect.txHash.toString(), // TODO: ⚠️ remove hash from txEffect txHash: txEffect.txHash.toString(), }; }); @@ -36,7 +35,6 @@ export const parseBlock = (b: L2Block): ChicmozL2Block => { totalFees: blockWithTxEffectsHashesAdded.header.totalFees.toBigInt(), contentCommitment: { ...blockWithTxEffectsHashesAdded.header.contentCommitment, - txsEffectsHash: b.header.contentCommitment.blobsHash, // TODO: ⚠️ find real txsEffectsHash (or remove it) }, globalVariables: { ...blockWithTxEffectsHashesAdded.header.globalVariables, diff --git a/packages/types/src/api/index.ts b/packages/types/src/api/index.ts index 31d26e71..6ed6de22 100644 --- a/packages/types/src/api/index.ts +++ b/packages/types/src/api/index.ts @@ -28,7 +28,7 @@ export const chicmozSearchResultsSchema = z.object({ ), txEffects: z.array( z.object({ - hash: chicmozL2TxEffectSchema.shape.hash, + txHash: chicmozL2TxEffectSchema.shape.txHash, partOfBlockWithHash: chicmozL2BlockSchema.shape.hash.optional(), }) ), diff --git a/packages/types/src/aztec/l2Block.ts b/packages/types/src/aztec/l2Block.ts index 62d83aa9..ddeb32c9 100644 --- a/packages/types/src/aztec/l2Block.ts +++ b/packages/types/src/aztec/l2Block.ts @@ -27,7 +27,7 @@ export const chicmozL2BlockSchema = z.object({ }), contentCommitment: z.object({ numTxs: frNumberSchema, - txsEffectsHash: bufferSchema, + blobsHash: bufferSchema, inHash: bufferSchema, outHash: bufferSchema, }), diff --git a/packages/types/src/aztec/l2TxEffect.ts b/packages/types/src/aztec/l2TxEffect.ts index 9071cee8..dd98cf6f 100644 --- a/packages/types/src/aztec/l2TxEffect.ts +++ b/packages/types/src/aztec/l2TxEffect.ts @@ -51,9 +51,6 @@ export const chicmozL2TxEffectSchema = z.object({ }, z.object({ code: z.number() }) ), - /** The hash of the transaction that caused these effects. */ - hash: hexStringSchema, - /** The hash of the transaction and its effects. */ txHash: hexStringSchema, txBirthTimestamp: z.number().optional(), transactionFee: frNumberSchema, diff --git a/packages/types/src/aztec/special.ts b/packages/types/src/aztec/special.ts index 6672c530..07e8e87f 100644 --- a/packages/types/src/aztec/special.ts +++ b/packages/types/src/aztec/special.ts @@ -48,7 +48,7 @@ export type ChicmozL2TxEffectDeluxe = z.infer< export const chicmozL2BlockLightSchema = z.object({ ...chicmozL2BlockSchema.shape, body: z.object({ - txEffects: z.array(chicmozL2TxEffectSchema.pick({ hash: true })), + txEffects: z.array(chicmozL2TxEffectSchema.pick({ txHash: true })), }), }); diff --git a/packages/types/src/general.ts b/packages/types/src/general.ts index 0d7ce7ff..d4ee2a3e 100644 --- a/packages/types/src/general.ts +++ b/packages/types/src/general.ts @@ -1,6 +1,6 @@ import { z } from "zod"; import { frSchema } from "./aztec/utils.js"; -import { ChicmozL2Block, ChicmozL2PendingTx } from "./index.js"; +import { ChicmozL2Block, ChicmozL2PendingTx, chicmozL2BlockSchema } from "./index.js"; export const hexStringSchema = z.custom<`0x${string}`>( (value) => { @@ -29,7 +29,26 @@ export const aztecAddressSchema = frSchema; export type AztecAddress = z.infer; -export type WebsocketUpdateMessage = { +const stringableChicmozL2BlockSchema = z.lazy(() => { + return z.object({ + ...chicmozL2BlockSchema.shape, + header: z.object({ + ...chicmozL2BlockSchema.shape.header.shape, + totalFees: z.string(), + }), + }); +}); + +export type StringableChicmozL2Block = z.infer< + typeof stringableChicmozL2BlockSchema +>; + +export type WebsocketUpdateMessageSender = { + block?: StringableChicmozL2Block; + txs?: ChicmozL2PendingTx[]; +}; + +export type WebsocketUpdateMessageReceiver = { block?: ChicmozL2Block; txs?: ChicmozL2PendingTx[]; }; diff --git a/services/event-cannon/src/contract-projects/SimpleLogging/Nargo.toml b/services/event-cannon/src/contract-projects/SimpleLogging/Nargo.toml index addf43f9..d0bb2b1e 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.67.0", directory = "noir-projects/aztec-nr/aztec" } +aztec = { git = "https://github.com/AztecProtocol/aztec-packages/", tag = "aztec-packages-v0.68.0", directory = "noir-projects/aztec-nr/aztec" } 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 7d9eaa04..d665cc6b 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 @@ -92,11 +92,67 @@ "brillig_names": ["compute_note_hash_and_optionally_a_nullifier"] }, { - "name": "increase_counter_public", + "name": "constructor", "is_unconstrained": true, - "custom_attributes": ["public"], + "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": "sync_notes", + "is_unconstrained": true, + "custom_attributes": [], + "abi": { + "error_types": { + "17843811134343075018": { + "error_kind": "string", + "string": "Stack too deep" + } + }, + "parameters": [], + "return_type": null + }, + "bytecode": "H4sIAAAAAAAA/9VUyw6CMBBseURBOaiJ3kz8gyIYOJJ49x8akKMe8OKNT5eabbqpVRKlJkzSbEs3szNlW0oUKESPvAH9tGnIFdhBDCA6aN/tRgFr9hviQKs7JH/O0iQw+BtQ/5OfWtIvIPktnT+bAM+xVfzYi6w77UaIesKWZ/nPbHpe9fhc/MFnh32k1caghm+uIYci3RuYR4Y8iRlRd9prh/eV5YzJei7w++RVO67va/lrWIeafvmOFV/qrDMe1wmv+YFXVVrypcYv4KBzGnMvbGHe1wvY45yo3mjul/J0vZ0b0gNB8gCVxsvQjgYAAA==", + "debug_symbols": "nZLNCoQgFIXf5a5bpGk/vkoMYWUhiIbZwBC9+1g0QzO00c2FI+c7G78VetEuYyP1YGZg9QrKdNxJo31atwRaK5WSY3N9hnQ/CB39eeJ6j7Pj1gHLcAJC98BI6ulBKgEsx9sjAYQD+1lgnwT2aVgf3+5XBFUnURGSfxlEyQHRGCiPgYoYqIyAstuPr2hafiCKi19o8/HJreStEqdYw6K7i2fuNYk/5SZrOtEvVuzyXbzzt0ZFgrGf9dNv", + "brillig_names": ["sync_notes"] + }, + { + "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" @@ -109,6 +165,10 @@ "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" @@ -125,9 +185,68 @@ ], "return_type": null }, - "bytecode": "JgACBAEnAAABBIBEJgAABAMmAgIEASYCAwQAHxgAAwACgEMtCIBDAAEkAAAAQCcCAAEEgEQmAgIEADoNAAEAAiQAAANzLAgBAwAAAQIBJgIEAQAsDgQDLAgBAwAAAQIBJgIEAAAsDgQDLAgBAwAAAQIBJgIFAAIsDgUDHgIAAwAeAgAFADI4AAMABQAGJgIDAQEjAgAGAAAAnyQAAAOcJgIDAmwmAgUCZCYCBgJjJgIHAnImAggCbiYCCQJDJgIKAmImAgsCcyYCDAJpJgINAmUmAg4CdSYCDwJwJgIQAmEmAhECICYCEgJ0JgITAm8sCAEUJgIVBBkAEAEVASYDFAQBACgUAhUsDBUWLA4JFgAoFgIWLA4TFgAoFgIWLA4OFgAoFgIWLA4IFgAoFgIWLA4SFgAoFgIWLA4NFgAoFgIWLA4HFgAoFgIWLA4RFgAoFgIWLA4MFgAoFgIWLA4IFgAoFgIWLA4GFgAoFgIWLA4HFgAoFgIWLA4NFgAoFgIWLA4QFgAoFgIWLA4LFgAoFgIWLA4NFgAoFgIWLA4FFgAoFgIWLA4RFgAoFgIWLA4PFgAoFgIWLA4OFgAoFgIWLA4KFgAoFgIWLA4DFgAoFgIWLA4MFgAoFgIWLA4GFiwIAQMmAgUEGQAQAQUBJgMDBAEAKAMCBSYCBgQYADgGBQYsDAUHDDgHBggWDAgIIwIACAAAAiMsDgQHACgHAgciAAACBCwNAwQAKAQCBCwOBAMsCAEEAAABAgEsDgMEJgIDBAAmAgUEASYCBgQYLAwDAiIAAAJVDDgCBgEjAgABAAAC5CIAAAJnLA0EASYCBAQYBigEAgImAgcEAwA4BAcFLAgBAwAQAQUBJgMDBAEAKAMCBSwOBAUAKAUCBSwOBAUmAgcEAwA4AwcFACgBAgctBAAHgAMtBAAFgAQtBAAEgAUkAAADrgAoAwIFLA0FBCYCBwQCADgFBwE2DQABAAQeAgABACUsDQQBJgIHBBgMOAIHCCMCAAgAAAL/JAAAA/QAKBQCBwA4BwIILA0IAxwMAwcAJgIIBBgMOAIICSMCAAkAAAMpJAAAA/QtBAABgAMnAIAEBAAZJAAABAYtCIAFAAMAKAMCCAA4CAIJLA4HCQA4AgUBDjgCAQcjAgAHAAADZiQAAASULA4DBCwMAQIiAAACVScAgAQEeAANAAAAgASAAyMAgAMAAAObKQEAAQX3ofOvpa3UyjsBAQIlKQEAAQW+Hj//PqT2+jsBAQIlAQCAA4AFgActAIADgAgtAIAEgAkLAIAIgAeACiMAgAoAAAPzLQGACIAGLQKABoAJAQCACAACgAgBAIAJAAKACSIAAAPCJSkBAAEF6J0J/qERLQ47AQECJS0BgAOABgsAgAYAAoAHIwCABwAABCEiAAAELC0AgAOABSIAAASTLQAAAYAFAQAAAYAEAAEBAIADgASACS0AgAOACi0AgAWACwsAgAqACYAMIwCADAAABH8tAYAKgAgtAoAIgAsBAIAKAAKACgEAgAsAAoALIgAABE4nAYAFBAABAwCABgACgAYiAAAEkyUpAQABBUWnynEZQeQVOwEBAiUtABjKGMo=", - "debug_symbols": "zVvbbiIxDP2XeZ6H+JLE6a+sqoq2tEJCUFG60qri3zfQDr1Qijgi4BdEkM+cE9tJnAx57e7Hty+PN5PZw/y5u/rz2k3nd6PlZD6rrddV390uJtPp5PHm889dWH+ksrF/fhrN1s3n5Wix7K4oldB349l9/ZpDqE94mEzH3VXi1XXfZQEwdjzGAB7Lx2MKAZh0PIYCIaCIgICwEikCQpj42Mj2u8YhxME4cNwaU6YfrFXM3q1VSv6wZvvB2kiGZxtF+mK9kW8nkG88GFf9Z5Uvp/C+0tb76ZD3Kcogn2LRA/IL8/Dswkl35CudVH4dYF/kbyhSc4qo7SmQoZmQSQBZRSgjTBlhMoTJEKaCMBWAiYMiIIQJWRYYWRaYESZGmARhEoRJBQEB1RJHhCkiTAlhSkBlxpkQEFCbsQUEFBEQkkbIxMIFCK4EQUBAcIUYAQHBFSYEBARXJCAgRUBAGgkyGwkyG0lEghuRNEpIcBOSRhkJbkbSCClzBClz6sYCABUkjQoQXA2MgIDgKhECAoKrHBCQIiAgjVQEAQFppIoEV5E0ikhwI5JGCQluQtII2XQpsunSPYd3dY4fQGIH9qqWh62qlbT6/QBAhAbj+vXjbKSeC2zkGPuSk13JKb68U1x5JwZX3onBl3fIl3f21PqXkrNnF3ExOdGVnD1lw8Xk+BpZ6mtkqS/vRF8jK/qad/aUlBeTo77kFFdyzl7vbF+t1WOk8l1OonMvEkm3crLsyjllsMrnd15vLwcTa2uC1j2Q1j2Q1j1QaU1gjQli6x7E1j1I3JogNybI1JogNSaw1j2w1j0orbOoNB4HOWhrghPMpjFsCezAAlvq6fFgXA8od+SQ+pJjruSw+JLjyzt7Kg/VNMjRlH6Xc9I/qmUNnmrprOfe+OS0lWO6K6e4khN9eSexLznZlZzsyzvZl3eMLienyK6ccx9H/bqHz4V8yXHlHQvqS05xJcfXcZQx+5KTXck5+xudA3LMlRz15R31lTvR18iKvryTfE2DOfiRs6rNv6PFZHQ7Hb/fXnx4md19usy4/Pc0/nav8WkxvxvfvyzG6xuOH5cb193iID2z1m6uxytZ6amU6/UVuU0z9GRx3aSNbeg5cNVQdfwH", - "brillig_names": ["increase_counter_public"] + "bytecode": "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", + "debug_symbols": "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", + "brillig_names": ["add_to_counter_public"] + }, + { + "name": "public_dispatch", + "is_unconstrained": true, + "custom_attributes": ["public"], + "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" + }, + "16541607464495309456": { + "error_kind": "fmtstring", + "item_types": [], + "length": 16 + }, + "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" + }, + "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" + } + }, + "parameters": [ + { + "name": "selector", + "type": { + "kind": "field" + }, + "visibility": "private" + } + ], + "return_type": null + }, + "bytecode": "JgACBAEnAAABBIBEJgAABAMmAgIEASYCAwQAHxgAAwACgEMtCIBDAAEkAAAAQCcCAAEEgEQmAgIEADoNAAEAAiQAAAeVKAIAAgAX8SiICjgBAgMmAgQEACYCBgQDADgEBgUsCAECABABBQEmAwIEAQAoAgIFLA4EBQAoBQIFLA4EBSYCBQQDADgCBQQmAgQEACMCAAMAAACeIgAAAOAmAgMEBSwIAAUAEAADACQAAAe+LAQAACwNAgMAKAMCAywOAwIAKAICBiwNBgUmAgcEAgA4BgcDOg0AAwAFIgAAAOAoAgADAJI5JNYKOAEDBSYCAwEAJgIGAAYmAgcEASYCCAAAIwIABQAAAQ8iAAACnywIAQUmAgkEAgAQAQkBJgMFBAEAKAUCCR88AAcABwAJLA0FCQAoCQIJLA4JBSwIAQkAAAECASwOBQksCAEFAAABAgEsDgQFJgILBAwsCAAMLAwJDSwMBQ4sDAYPABAACwAkAAAKviwEAAAsDA0KLAgBBQAAAQIBLA4DBSwIAQkAAAECASwOCAksCAELAAABAgEmAgwAKiwODAsmAgwEDSwIAA0sDAUOLAwJDywMCxAAEAAMACQAAAsZLAQAAB4CAAwBHgIADQAKOAwNDiMCAA4AAAHoJAAAC0MmAgwAASYCDQAZJgISBBMsCAATLAwFFCwMCRUsDAsWLAwMFywMDRgsDAoZABAAEgAkAAALVSwEAAAsDBQOLAwVDywMFhAsDBcRLgwAEQASADgSDBEmAhYEFywIABcsDAUYLAwJGSwMCxosDAwbLAwNHCwMCh0AEAAWACQAAAtVLAQAACwMGBIsDBkTLAwaFCwMGxUvDAARABUAKAICCiwNCgkmAgsEAgA4CgsFOg0ABQAJIgAAAp8oAgAFAK/cIDsKOAEFCSYCAQJzJgIFAmUmAgoCbCYCCwJjJgIMAnImAg0CbiYCDgIgJgIPAnQmAhACbyMCAAkAAALnIgAABdwsCAERJgISBAIAEAESASYDEQQBACgRAhIfPAAHAAcAEiwNERIAKBICEiwOEhEsCAESAAABAgEsDhESLAgBEQAAAQIBLA4EESYCFAQVLAgAFSwMEhYsDBEXLAwGGAAQABQAJAAACr4sBAAALAwWEywIAQYAAAECASwOAwYsCAERAAABAgEsDggRLAgBEgAAAQIBJgIUAAssDhQSJgIUBBUsCAAVLAwGFiwMERcsDBIYABAAFAAkAAALGSwEAAAmAgYCYiYCEQJpJgISAnUmAhQCZCYCFQJDJgIWAnAmAhcCYSwIARgmAhkEGQAQARkBJgMYBAEAKBgCGSwMGRosDhUaACgaAhosDhAaACgaAhosDhIaACgaAhosDg0aACgaAhosDg8aACgaAhosDgUaACgaAhosDgwaACgaAhosDg4aACgaAhosDhEaACgaAhosDg0aACgaAhosDgsaACgaAhosDgwaACgaAhosDgUaACgaAhosDhcaACgaAhosDgEaACgaAhosDgUaACgaAhosDhQaACgaAhosDg4aACgaAhosDhYaACgaAhosDhIaACgaAhosDgYaACgaAhosDgoaACgaAhosDhEaACgaAhosDgsaLAgBBiYCEQQZABABEQEmAwYEAQAoBgIRJgISBBgAOBIREiwMERQMOBQSFRYMFRUjAgAVAAAE+ywOCBQAKBQCFCIAAATcLA0GCAAoCAIILA4IBiwIAQgAAAECASwOBggmAgYEGCwMBAkiAAAFIww4CQYRIwIAEQAABwYiAAAFNSwNCAcmAhEEGAYoEQIIJgITBAMAOBETEiwIAQkAEAESASYDCQQBACgJAhIsDhESACgSAhIsDhESJgITBAMAOAkTEgAoBwITLQQAE4ADLQQAEoAELQQAEYAFJAAADQ4AKAkCEiwNEhEmAhMEAgA4EhMHNg0ABwARHgIABgAsDQIHACgHAgcsDgcCACgCAhEsDREJJgISBAIAOBESBzoNAAcACSIAAAXcJgICAlUmAgYCayYCBwJ3LAgBCCYCCQQRABABCQEmAwgEAQAoCAIJLAwJESwOAhEAKBECESwODREAKBECESwOBhEAKBECESwODREAKBECESwOEBEAKBECESwOBxEAKBECESwODREAKBECESwODhEAKBECESwOAREAKBECESwOBREAKBECESwOChEAKBECESwOBREAKBECESwOCxEAKBECESwODxEAKBECESwOEBEAKBECESwODBEmAgEBAQo4AwECIwIAAgAABwUmAgUEEiwIAQYmAgcEEgAQAQcBLAwGBykDAAcF5Y+YWQcxYpAAKAcCBwAoCAIJJgIKBBAtBAAJgAMtBAAHgAQtBAAKgAUkAAANDiYCCQQQADgHCQcsDgQHACgHAgc7DQYFJSwN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", + "debug_symbols": "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", + "brillig_names": ["public_dispatch"] }, { "name": "increase_counter_private", @@ -249,7 +368,7 @@ } }, { - "name": "txs_effects_hash", + "name": "blobs_hash", "type": { "kind": "field" } @@ -580,6 +699,27 @@ "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", @@ -1348,7 +1488,7 @@ } }, { - "name": "txs_effects_hash", + "name": "blobs_hash", "type": { "kind": "field" } @@ -1679,6 +1819,27 @@ "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", @@ -1697,117 +1858,32 @@ "visibility": "databus" } }, - "bytecode": "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", - "debug_symbols": "7ZbdisIwEIXfJde9yMzkb3yVZZGqVQqllVoXFvHdNylNq25YWcsuCN6UTvNN5uRMEnoSm2J13C3LetscxOLtJKpmnXdlU/voJID6b4d9Xofw0OVtJxZgWGaiqDf+1Up5zsS2rAqxMHjOvsHoyA0wOjPBQDJBkwYeaNKMd2jHVg+0Y8cjjUgJGqyjKNvJaW40KViiibC0+hJ+zwSoly9JX/TLl6Qv5uVL0hc72xclddSuJMO0UpR9BffnFXh2Bd8VFWGiyX+wkKCZNQw0s3FXehL7BsnFyREV0K1+lE+uH1L6GXHcdlL/LN+StgNsyV0cFkzJ1y4aY2CaGJTuxeB8MRxhq8jeEQMMKmr370bNdpOefQHqvxdgzXhSmNXN/eCjVVtWVblbXv1ZyfBQyd0CIOP5AEB3u8UUPZKkHknSjySZXyf5CAKbvon01A19cbXokOjDj7wt81VVBFfD6LFeR5N92H3u40hsw75t1sXm2BahIVMvgqskMyXDlR6EKJdpGrX1n5AydL6qr/wF", + "bytecode": "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", + "debug_symbols": "7ZbtasIwFIbvJb/7I+crH97KGKNqJ4VSpepgiPe+RJpWXZxM2UDwT+lpnpPz5j1J6E7Nq+l28Va378u1mrzsVLOclZt62YZop4AO39arso3helN2GzUB43WhqnYeXq3W+0K9102lJgb3xTcYHbkeRmdGGEhnaBLwPU3i8QoNhmVQYtjwwCNSjreOEu70ODuaHKzRJFhbOYZfCwX8dOaCM/J05oIz5unMBWfs3c6wFulh1h7GtaI+VHB/XsHfXSH0hRNM5McKFjK09wI97b1xJ3oyOwfJpckRGehcP+oH1w85/R5x2HZafpZvSWwPW3JHxwVz8sUlYwyMEwPLQQzeL8Yn2DLZK2LAAyft4f3o7N7qJj36Avi/F2DNcFK857P7IUTTrm6aevF28oel44OzuwVAp/MBgO58izHdksS3JMktSebXSSGCyOZvIhm7IUdXi8TEEH6UXV1Omyq6Gke37SyZHMLN5yqNpDasuuWsmm+7KjZk7EV0lXTBOl7pUQi7QmjQdviEVKALVUPlLw==", "brillig_names": [ "pack_arguments_oracle_wrapper", "enqueue_public_function_call_internal" ], - "verification_key": "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" + "verification_key": "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" }, { - "name": "sync_notes", - "is_unconstrained": true, - "custom_attributes": [], - "abi": { - "error_types": { - "17843811134343075018": { - "error_kind": "string", - "string": "Stack too deep" - } - }, - "parameters": [], - "return_type": null - }, - "bytecode": "H4sIAAAAAAAA/9VUyw6CMBBseURBOaiJ3kz8gyIYOJJ49x8akKMe8OKNT5eabbqpVRKlJkzSbEs3szNlW0oUKESPvAH9tGnIFdhBDCA6aN/tRgFr9hviQKs7JH/O0iQw+BtQ/5OfWtIvIPktnT+bAM+xVfzYi6w77UaIesKWZ/nPbHpe9fhc/MFnh32k1caghm+uIYci3RuYR4Y8iRlRd9prh/eV5YzJei7w++RVO67va/lrWIeafvmOFV/qrDMe1wmv+YFXVVrypcYv4KBzGnMvbGHe1wvY45yo3mjul/J0vZ0b0gNB8gCVxsvQjgYAAA==", - "debug_symbols": "nZJLCoMwFEX38sYOzM/fVqRI1CiBkEiMhSLuvVFsscVJMnlwwz13krNCL9plbKQezAxVvYIyHXfSaJ/WLYHWSqXk2FyfId0PQkd/nrje4+y4dVARnIDQPVQ09fQglYAqw9sjAYQD+ySwTwP7LKyPb/dLUmYnUVJMvgxi9IBYDJTFQHkMVERA5PbjS1qwD8RS+gttPj65lbxV4hRrWHR38cy9JvGn3GRNJ/rFil2+i3f+1ihPMPazfvoN", - "brillig_names": ["sync_notes"] - }, - { - "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": "public_dispatch", + "name": "increase_counter_public", "is_unconstrained": true, "custom_attributes": ["public"], "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" }, - "16541607464495309456": { - "error_kind": "fmtstring", - "item_types": [], - "length": 16 - }, "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" }, - "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" @@ -1815,7 +1891,7 @@ }, "parameters": [ { - "name": "selector", + "name": "counter_id", "type": { "kind": "field" }, @@ -1824,43 +1900,9 @@ ], "return_type": null }, - "bytecode": "JgACBAEnAAABBIBEJgAABAMmAgIEASYCAwQAHxgAAwACgEMtCIBDAAEkAAAAQCcCAAEEgEQmAgIEADoNAAEAAiQAAAeVKAIAAgAX8SiICjgBAgMmAgQEACYCBgQDADgEBgUsCAECABABBQEmAwIEAQAoAgIFLA4EBQAoBQIFLA4EBSYCBQQDADgCBQQmAgQEACMCAAMAAACeIgAAAOAmAgMEBSwIAAUAEAADACQAAAe+LAQAACwNAgMAKAMCAywOAwIAKAICBiwNBgUmAgcEAgA4BgcDOg0AAwAFIgAAAOAoAgADAJI5JNYKOAEDBSYCAwEAJgIGAAYmAgcEASYCCAAAIwIABQAAAQ8iAAACnywIAQUmAgkEAgAQAQkBJgMFBAEAKAUCCR88AAcABwAJLA0FCQAoCQIJLA4JBSwIAQkAAAECASwOBQksCAEFAAABAgEsDgQFJgILBAwsCAAMLAwJDSwMBQ4sDAYPABAACwAkAAAKviwEAAAsDA0KLAgBBQAAAQIBLA4DBSwIAQkAAAECASwOCAksCAELAAABAgEmAgwAKiwODAsmAgwEDSwIAA0sDAUOLAwJDywMCxAAEAAMACQAAAsZLAQAAB4CAAwBHgIADQAKOAwNDiMCAA4AAAHoJAAAC0MmAgwAASYCDQAZJgISBBMsCAATLAwFFCwMCRUsDAsWLAwMFywMDRgsDAoZABAAEgAkAAALVSwEAAAsDBQOLAwVDywMFhAsDBcRLgwAEQASADgSDBEmAhYEFywIABcsDAUYLAwJGSwMCxosDAwbLAwNHCwMCh0AEAAWACQAAAtVLAQAACwMGBIsDBkTLAwaFCwMGxUvDAARABUAKAICCiwNCgkmAgsEAgA4CgsFOg0ABQAJIgAAAp8oAgAFAK/cIDsKOAEFCSYCAQJzJgIFAmUmAgoCbCYCCwJjJgIMAnImAg0CbiYCDgIgJgIPAnQmAhACbyMCAAkAAALnIgAABdwsCAERJgISBAIAEAESASYDEQQBACgRAhIfPAAHAAcAEiwNERIAKBICEiwOEhEsCAESAAABAgEsDhESLAgBEQAAAQIBLA4EESYCFAQVLAgAFSwMEhYsDBEXLAwGGAAQABQAJAAACr4sBAAALAwWEywIAQYAAAECASwOAwYsCAERAAABAgEsDggRLAgBEgAAAQIBJgIUAAssDhQSJgIUBBUsCAAVLAwGFiwMERcsDBIYABAAFAAkAAALGSwEAAAmAgYCYiYCEQJpJgISAnUmAhQCZCYCFQJDJgIWAnAmAhcCYSwIARgmAhkEGQAQARkBJgMYBAEAKBgCGSwMGRosDhUaACgaAhosDhAaACgaAhosDhIaACgaAhosDg0aACgaAhosDg8aACgaAhosDgUaACgaAhosDgwaACgaAhosDg4aACgaAhosDhEaACgaAhosDg0aACgaAhosDgsaACgaAhosDgwaACgaAhosDgUaACgaAhosDhcaACgaAhosDgEaACgaAhosDgUaACgaAhosDhQaACgaAhosDg4aACgaAhosDhYaACgaAhosDhIaACgaAhosDgYaACgaAhosDgoaACgaAhosDhEaACgaAhosDgsaLAgBBiYCEQQZABABEQEmAwYEAQAoBgIRJgISBBgAOBIREiwMERQMOBQSFRYMFRUjAgAVAAAE+ywOCBQAKBQCFCIAAATcLA0GCAAoCAIILA4IBiwIAQgAAAECASwOBggmAgYEGCwMBAkiAAAFIww4CQYRIwIAEQAABwYiAAAFNSwNCAcmAhEEGAYoEQIIJgITBAMAOBETEiwIAQkAEAESASYDCQQBACgJAhIsDhESACgSAhIsDhESJgITBAMAOAkTEgAoBwITLQQAE4ADLQQAEoAELQQAEYAFJAAADQ4AKAkCEiwNEhEmAhMEAgA4EhMHNg0ABwARHgIABgAsDQIHACgHAgcsDgcCACgCAhEsDREJJgISBAIAOBESBzoNAAcACSIAAAXcJgICAlUmAgYCayYCBwJ3LAgBCCYCCQQRABABCQEmAwgEAQAoCAIJLAwJESwOAhEAKBECESwODREAKBECESwOBhEAKBECESwODREAKBECESwOEBEAKBECESwOBxEAKBECESwODREAKBECESwODhEAKBECESwOAREAKBECESwOBREAKBECESwOChEAKBECESwOBREAKBECESwOCxEAKBECESwODxEAKBECESwOEBEAKBECESwODBEmAgEBAQo4AwECIwIAAgAABwUmAgUEEiwIAQYmAgcEEgAQAQcBLAwGBykDAAcF5Y+YWQcxYpAAKAcCBwAoCAIJJgIKBBAtBAAJgAMtBAAHgAQtBAAKgAUkAAANDiYCCQQQADgHCQcsDgQHACgHAgc7DQYFJSwN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", - "debug_symbols": "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", - "brillig_names": ["public_dispatch"] - }, - { - "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"] + "bytecode": "JgACBAEnAAABBIBEJgAABAMmAgIEASYCAwQAHxgAAwACgEMtCIBDAAEkAAAAQCcCAAEEgEQmAgIEADoNAAEAAiQAAANzLAgBAwAAAQIBJgIEAQAsDgQDLAgBAwAAAQIBJgIEAAAsDgQDLAgBAwAAAQIBJgIFAAIsDgUDHgIAAwAeAgAFADI4AAMABQAGJgIDAQEjAgAGAAAAnyQAAAOcJgIDAmwmAgUCZCYCBgJjJgIHAnImAggCbiYCCQJDJgIKAmImAgsCcyYCDAJpJgINAmUmAg4CdSYCDwJwJgIQAmEmAhECICYCEgJ0JgITAm8sCAEUJgIVBBkAEAEVASYDFAQBACgUAhUsDBUWLA4JFgAoFgIWLA4TFgAoFgIWLA4OFgAoFgIWLA4IFgAoFgIWLA4SFgAoFgIWLA4NFgAoFgIWLA4HFgAoFgIWLA4RFgAoFgIWLA4MFgAoFgIWLA4IFgAoFgIWLA4GFgAoFgIWLA4HFgAoFgIWLA4NFgAoFgIWLA4QFgAoFgIWLA4LFgAoFgIWLA4NFgAoFgIWLA4FFgAoFgIWLA4RFgAoFgIWLA4PFgAoFgIWLA4OFgAoFgIWLA4KFgAoFgIWLA4DFgAoFgIWLA4MFgAoFgIWLA4GFiwIAQMmAgUEGQAQAQUBJgMDBAEAKAMCBSYCBgQYADgGBQYsDAUHDDgHBggWDAgIIwIACAAAAiMsDgQHACgHAgciAAACBCwNAwQAKAQCBCwOBAMsCAEEAAABAgEsDgMEJgIDBAAmAgUEASYCBgQYLAwDAiIAAAJVDDgCBgEjAgABAAAC5CIAAAJnLA0EASYCBAQYBigEAgImAgcEAwA4BAcFLAgBAwAQAQUBJgMDBAEAKAMCBSwOBAUAKAUCBSwOBAUmAgcEAwA4AwcFACgBAgctBAAHgAMtBAAFgAQtBAAEgAUkAAADrgAoAwIFLA0FBCYCBwQCADgFBwE2DQABAAQeAgABACUsDQQBJgIHBBgMOAIHCCMCAAgAAAL/JAAAA/QAKBQCBwA4BwIILA0IAxwMAwcAJgIIBBgMOAIICSMCAAkAAAMpJAAAA/QtBAABgAMnAIAEBAAZJAAABAYtCIAFAAMAKAMCCAA4CAIJLA4HCQA4AgUBDjgCAQcjAgAHAAADZiQAAASULA4DBCwMAQIiAAACVScAgAQEeAANAAAAgASAAyMAgAMAAAObKQEAAQX3ofOvpa3UyjsBAQIlKQEAAQW+Hj//PqT2+jsBAQIlAQCAA4AFgActAIADgAgtAIAEgAkLAIAIgAeACiMAgAoAAAPzLQGACIAGLQKABoAJAQCACAACgAgBAIAJAAKACSIAAAPCJSkBAAEF6J0J/qERLQ47AQECJS0BgAOABgsAgAYAAoAHIwCABwAABCEiAAAELC0AgAOABSIAAASTLQAAAYAFAQAAAYAEAAEBAIADgASACS0AgAOACi0AgAWACwsAgAqACYAMIwCADAAABH8tAYAKgAgtAoAIgAsBAIAKAAKACgEAgAsAAoALIgAABE4nAYAFBAABAwCABgACgAYiAAAEkyUpAQABBUWnynEZQeQVOwEBAiUtABjKGMo=", + "debug_symbols": "zVvbbiIxDP2XeZ6H+JLE6a+sqoq2tEJCUFG60qri3zfQDr1Qijgi4BdEkM+cE9tJnAx57e7Hty+PN5PZw/y5u/rz2k3nd6PlZD6rrddV390uJtPp5PHm889dWH+ksrF/fhrN1s3n5Wix7K4oldB349l9/ZpDqE94mEzH3VXi1XXfZQEwdjzGAB7Lx2MKAZh0PIYCIaCIgICwEikCQpj42Mj2u8YhxME4cNwaU6YfrFXM3q1VSv6wZvvB2kiGZxtF+mK9kW8nkG88GFf9Z5Uvp/C+0tb76ZD3Kcogn2LRA/IL8/Dswkl35CudVH4dYF/kbyhSc4qo7SmQoZmQSQBZRSgjTBlhMoTJEKaCMBWAiYMiIIQJWRYYWRaYESZGmARhEoRJBQEB1RJHhCkiTAlhSkBlxpkQEFCbsQUEFBEQkkbIxMIFCK4EQUBAcIUYAQHBFSYEBARXJCAgRUBAGgkyGwkyG0lEghuRNEpIcBOSRhkJbkbSCClzBClz6sYCABUkjQoQXA2MgIDgKhECAoKrHBCQIiAgjVQEAQFppIoEV5E0ikhwI5JGCQluQtII2XQpsunSPYd3dY4fQGIH9qqWh62qlbT6/QBAhAbj+vXjbKSeC2zkGPuSk13JKb68U1x5JwZX3onBl3fIl3f21PqXkrNnF3ExOdGVnD1lw8Xk+BpZ6mtkqS/vRF8jK/qad/aUlBeTo77kFFdyzl7vbF+t1WOk8l1OonMvEkm3crLsyjllsMrnd15vLwcTa2uC1j2Q1j2Q1j1QaU1gjQli6x7E1j1I3JogNybI1JogNSaw1j2w1j0orbOoNB4HOWhrghPMpjFsCezAAlvq6fFgXA8od+SQ+pJjruSw+JLjyzt7Kg/VNMjRlH6Xc9I/qmUNnmrprOfe+OS0lWO6K6e4khN9eSexLznZlZzsyzvZl3eMLienyK6ccx9H/bqHz4V8yXHlHQvqS05xJcfXcZQx+5KTXck5+xudA3LMlRz15R31lTvR18iKvryTfE2DOfiRs6rNv6PFZHQ7Hb/fXnx4md19usy4/Pc0/nav8WkxvxvfvyzG6xuOH5cb193iID2z1m6uxytZ6amU6/UVuU0z9GRx3aSNbeg5cNVQdfwH", + "brillig_names": ["increase_counter_public"] }, { "name": "get_counter_value", @@ -1902,7 +1944,7 @@ } }, "bytecode": "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", - "debug_symbols": "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", + "debug_symbols": "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", "brillig_names": ["get_counter_value"] } ], @@ -1963,12 +2005,12 @@ } ], "kind": "struct", - "path": "SimpleLogging::increase_counter_public_parameters" + "path": "SimpleLogging::increase_counter_private_parameters" } } ], "kind": "struct", - "path": "SimpleLogging::increase_counter_public_abi" + "path": "SimpleLogging::increase_counter_private_abi" }, { "fields": [ @@ -1984,142 +2026,142 @@ } ], "kind": "struct", - "path": "SimpleLogging::increase_counter_private_parameters" + "path": "SimpleLogging::add_to_counter_public_parameters" } } ], "kind": "struct", - "path": "SimpleLogging::increase_counter_private_abi" + "path": "SimpleLogging::add_to_counter_public_abi" }, { "fields": [ { "name": "parameters", "type": { - "fields": [], + "fields": [ + { + "name": "counter_id", + "type": { + "kind": "field" + } + } + ], "kind": "struct", - "path": "SimpleLogging::constructor_parameters" + "path": "SimpleLogging::increase_counter_public_parameters" } } ], "kind": "struct", - "path": "SimpleLogging::constructor_abi" + "path": "SimpleLogging::increase_counter_public_abi" }, { "fields": [ { "name": "parameters", "type": { - "fields": [ - { - "name": "counter_id", - "type": { - "kind": "field" - } - } - ], + "fields": [], "kind": "struct", - "path": "SimpleLogging::add_to_counter_public_parameters" + "path": "SimpleLogging::constructor_parameters" } } ], "kind": "struct", - "path": "SimpleLogging::add_to_counter_public_abi" + "path": "SimpleLogging::constructor_abi" } ] } }, "file_map": { "103": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.67.0/noir-projects/aztec-nr/aztec/src/state_vars/map.nr", + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.68.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\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" }, "116": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.67.0/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr", + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.68.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\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" }, "120": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.67.0/noir-projects/aztec-nr/aztec/src/context/private_context.nr", + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.68.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, packed_returns::PackedReturns},\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 arguments,\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 key_validation_request::get_key_validation_request,\n returns::pack_returns,\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 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 self.nullifiers.push(\n Nullifier {\n value: nullifier,\n note_hash: nullified_note_hash,\n counter: self.next_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 pack_returns(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 let request = unsafe { get_key_validation_request(pk_m_hash, key_index) };\n assert(request.pk_m.hash() == pk_m_hash);\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 ) -> PackedReturns {\n let args_hash = hash_args_array(args);\n arguments::pack_arguments_array(args);\n self.call_private_function_with_packed_args(\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 ) -> PackedReturns {\n let args_hash = hash_args_array(args);\n arguments::pack_arguments_array(args);\n self.call_private_function_with_packed_args(\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 ) -> PackedReturns {\n self.call_private_function_with_packed_args(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 ) -> PackedReturns {\n self.call_private_function_with_packed_args(contract_address, function_selector, 0, true)\n }\n\n pub fn call_private_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field,\n is_static_call: bool,\n ) -> PackedReturns {\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 // The oracle simulates the private call and returns the value of the side effects counter after execution of\n // the call (which means that end_side_effect_counter - start_side_effect_counter is the number of side effects\n // that took place), along with the hash of the return values. We validate these by requesting a private kernel\n // iteration in which the return values are constrained to hash to `returns_hash` and the side effects counter\n // 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 PackedReturns::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 arguments::pack_arguments_array(args);\n self.call_public_function_with_packed_args(\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 arguments::pack_arguments_array(args);\n self.call_public_function_with_packed_args(\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_packed_args(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_packed_args(contract_address, function_selector, 0, true)\n }\n\n pub fn call_public_function_with_packed_args(\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 // TODO(https://github.com/AztecProtocol/aztec-packages/issues/8985): Fix this.\n // WARNING: This is insecure and should be temporary!\n // The oracle repacks 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 = enqueue_public_function_call_internal(\n contract_address,\n function_selector,\n args_hash,\n counter,\n is_static_call,\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 arguments::pack_arguments_array(args);\n self.set_public_teardown_function_with_packed_args(\n contract_address,\n function_selector,\n args_hash,\n false,\n )\n }\n\n pub fn set_public_teardown_function_with_packed_args(\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 // TODO(https://github.com/AztecProtocol/aztec-packages/issues/8985): Fix this.\n // WARNING: This is insecure and should be temporary!\n // The oracle repacks 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 = set_public_teardown_function_call_internal(\n contract_address,\n function_selector,\n args_hash,\n counter,\n is_static_call,\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" }, "121": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.67.0/noir-projects/aztec-nr/aztec/src/context/call_interfaces.nr", + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.68.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::arguments::pack_arguments;\n\npub trait CallInterface {\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 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 pack_arguments(self.args);\n let returns = context.call_private_function_with_packed_args(\n self.target_contract,\n self.selector,\n self.args_hash,\n false,\n );\n let unpacked: T = returns.unpack_into();\n unpacked\n }\n\n pub fn view(self, context: &mut PrivateContext) -> T\n where\n T: Deserialize,\n {\n pack_arguments(self.args);\n let returns = context.call_private_function_with_packed_args(\n self.target_contract,\n self.selector,\n self.args_hash,\n true,\n );\n returns.unpack_into()\n }\n}\n\nimpl CallInterface for PrivateVoidCallInterface {}\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 pack_arguments(self.args);\n context\n .call_private_function_with_packed_args(\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 pack_arguments(self.args);\n context\n .call_private_function_with_packed_args(\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\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 pack_arguments(self.args);\n let returns = context.call_private_function_with_packed_args(\n self.target_contract,\n self.selector,\n self.args_hash,\n true,\n );\n returns.unpack_into()\n }\n}\n\nimpl CallInterface for PrivateStaticVoidCallInterface {}\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 pack_arguments(self.args);\n context\n .call_private_function_with_packed_args(\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\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 pack_arguments(self.args);\n context.call_public_function_with_packed_args(\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 pack_arguments(self.args);\n context.call_public_function_with_packed_args(\n self.target_contract,\n self.selector,\n args_hash,\n /*static=*/\n true,\n )\n }\n}\n\nimpl CallInterface for PublicVoidCallInterface {}\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 pack_arguments(self.args);\n context.call_public_function_with_packed_args(\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 pack_arguments(self.args);\n context.call_public_function_with_packed_args(\n self.target_contract,\n self.selector,\n args_hash,\n /*static=*/\n true,\n )\n }\n}\n\nimpl CallInterface for PublicStaticCallInterface {}\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 pack_arguments(self.args);\n context.call_public_function_with_packed_args(\n self.target_contract,\n self.selector,\n args_hash,\n /*static=*/\n true,\n )\n }\n}\n\nimpl CallInterface for PublicStaticVoidCallInterface {}\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 pack_arguments(self.args);\n context.call_public_function_with_packed_args(\n self.target_contract,\n self.selector,\n args_hash,\n /*static=*/\n true,\n )\n }\n}\n" }, "122": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.67.0/noir-projects/aztec-nr/aztec/src/context/unconstrained_context.nr", + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.68.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" }, "128": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.67.0/noir-projects/aztec-nr/aztec/src/context/public_context.nr", + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.68.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 // 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 // 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 // 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 // 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 // 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 // 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 // AVM opcodes are constrained by the AVM itself\n unsafe { emit_nullifier(nullifier) };\n }\n\n pub fn this_address(_self: Self) -> AztecAddress {\n // AVM opcodes are constrained by the AVM itself\n unsafe {\n address()\n }\n }\n pub fn msg_sender(_self: Self) -> AztecAddress {\n // 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 // 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 // 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 // AVM opcodes are constrained by the AVM itself\n unsafe {\n chain_id()\n }\n }\n pub fn version(_self: Self) -> Field {\n // AVM opcodes are constrained by the AVM itself\n unsafe {\n version()\n }\n }\n pub fn block_number(_self: Self) -> Field {\n // AVM opcodes are constrained by the AVM itself\n unsafe {\n block_number()\n }\n }\n pub fn timestamp(_self: Self) -> u64 {\n // 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 // 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 // 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 // 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 // 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 // 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 // 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 // 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" }, "130": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.67.0/noir-projects/aztec-nr/aztec/src/hash.nr", + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.68.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" }, "145": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.67.0/noir-projects/aztec-nr/aztec/src/oracle/arguments.nr", + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.68.0/noir-projects/aztec-nr/aztec/src/oracle/arguments.nr", "source": "/// Notifies the simulator that `args` will later be used at some point during execution, referenced by their hash. This\n/// allows the simulator to know how to respond to this future request.\n///\n/// This is only used during private execution, since in public it is the VM itself that keeps track of arguments.\npub fn pack_arguments(args: [Field]) {\n // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe to call. When\n // unpacking however the caller must check that the returned value is indeed the preimage.\n unsafe { pack_arguments_oracle_wrapper(args) };\n}\n\n/// Same as `pack_arguments`, but using arrays instead of slices.\npub fn pack_arguments_array(args: [Field; N]) {\n // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe to call. When\n // unpacking however the caller must check that the returned value is indeed the preimage.\n unsafe { pack_arguments_array_oracle_wrapper(args) };\n}\n\nunconstrained fn pack_arguments_oracle_wrapper(args: [Field]) {\n let _ = pack_arguments_oracle(args);\n}\n\nunconstrained fn pack_arguments_array_oracle_wrapper(args: [Field; N]) {\n let _ = pack_arguments_array_oracle(args);\n}\n\n#[oracle(packArguments)]\nunconstrained fn pack_arguments_oracle(_args: [Field]) -> Field {}\n\n#[oracle(packArgumentsArray)]\nunconstrained fn pack_arguments_array_oracle(_args: [Field; N]) -> Field {}\n" }, "146": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.67.0/noir-projects/aztec-nr/aztec/src/oracle/get_contract_instance.nr", + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.68.0/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 let instance =\n unsafe { ContractInstance::deserialize(get_contract_instance_internal(address)) };\n // The to_address function combines all values in the instance object to produce an address, so by checking that we\n // get the expected address we validate the entire struct.\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 let (member, exists) = 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 let (member, exists) = 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 let (member, exists) = get_contract_instance_initialization_hash_internal_avm(address);\n if exists {\n Option::some(member)\n } else {\n Option::none()\n }\n}\n" }, "153": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.67.0/noir-projects/aztec-nr/aztec/src/oracle/execution.nr", + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.68.0/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" }, "154": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.67.0/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 // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe 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 // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe to call.\n unsafe { notify_nullified_note_oracle_wrapper(nullifier, note_hash, counter) };\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\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_app_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_app_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 ivpsk_m of the sender.\n/// For the recipient's side, only the address is needed.\npub unconstrained fn get_app_tagging_secret_as_sender(\n sender: AztecAddress,\n recipient: AztecAddress,\n) -> IndexedTaggingSecret {\n let result = get_app_tagging_secret_as_sender_oracle(sender, recipient);\n IndexedTaggingSecret::deserialize(result)\n}\n\n#[oracle(getAppTaggingSecretAsSender)]\nunconstrained fn get_app_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 // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe 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 // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe 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.68.0/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 // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe 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 // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe to call.\n unsafe { notify_nullified_note_oracle_wrapper(nullifier, note_hash, counter) };\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\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 // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe 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 // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe 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" }, "155": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.67.0/noir-projects/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr", + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.68.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 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" }, "156": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.67.0/noir-projects/aztec-nr/aztec/src/oracle/storage.nr", + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.68.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" }, "171": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.67.0/noir-projects/aztec-nr/aztec/src/initializer.nr", + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.68.0/noir-projects/aztec-nr/aztec/src/initializer.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\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" }, "177": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.67.0/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr", + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.68.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, 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::embedded_curve_ops::{EmbeddedCurveScalar, fixed_base_scalar_mul as derive_public_key};\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" }, "189": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.67.0/noir-projects/noir-protocol-circuits/crates/types/src/type_serialization.nr", + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.68.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" }, "207": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.67.0/noir-projects/noir-protocol-circuits/crates/types/src/utils/reader.nr", + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.68.0/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" }, "211": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.67.0/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\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 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: validate_array(array) should be true.\npub fn array_length(array: [T; N]) -> u32\nwhere\n T: Empty + Eq,\n{\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\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]\nfn find_index_greater_than_min() {\n let values = [10, 20, 30, 40];\n let min = 22;\n let index = unsafe { find_index_hint(values, |v: Field| min.lt(v)) };\n assert_eq(index, 2);\n}\n\n#[test]\nfn find_index_not_found() {\n let values = [10, 20, 30, 40];\n let min = 100;\n let index = unsafe { 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 concated = array_concat(array0, array1);\n assert_eq(concated, [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.68.0/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\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 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: validate_array(array) should be true.\npub fn array_length(array: [T; N]) -> u32\nwhere\n T: Empty + Eq,\n{\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]\nfn find_index_greater_than_min() {\n let values = [10, 20, 30, 40];\n let min = 22;\n let index = unsafe { find_index_hint(values, |v: Field| min.lt(v)) };\n assert_eq(index, 2);\n}\n\n#[test]\nfn find_index_not_found() {\n let values = [10, 20, 30, 40];\n let min = 100;\n let index = unsafe { 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 concated = array_concat(array0, array1);\n assert_eq(concated, [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" }, "221": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.67.0/noir-projects/noir-protocol-circuits/crates/types/src/traits.nr", + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.68.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" }, "223": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.67.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::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 traits::{is_empty, ToField},\n utils::field::field_from_bytes_32_trunc,\n};\nuse super::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\nfn compute_note_hash_nonce(tx_hash: Field, note_index_in_tx: u32) -> Field {\n // Hashing tx hash with note index in tx is guaranteed to be unique\n poseidon2_hash_with_separator(\n [tx_hash, 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 tx_hash: 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(tx_hash, 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: BoundedVec = BoundedVec::new();\n\n let inputs =\n [contract_address.to_field(), rollup_version_id, recipient.to_field(), chain_id, content];\n for i in 0..inputs.len() {\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.push(item_bytes[j]);\n }\n }\n\n sha256_to_field(bytes.storage())\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\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 two_pow_64 = 18446744073709551616;\n let iv: Field = (in_len as Field) * two_pow_64;\n let mut sponge = std::hash::poseidon2::Poseidon2::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 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.68.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::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 traits::{is_empty, ToField},\n utils::field::field_from_bytes_32_trunc,\n};\nuse super::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\nfn compute_note_hash_nonce(tx_hash: Field, note_index_in_tx: u32) -> Field {\n // Hashing tx hash with note index in tx is guaranteed to be unique\n poseidon2_hash_with_separator(\n [tx_hash, 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 tx_hash: 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(tx_hash, 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: BoundedVec = BoundedVec::new();\n\n let inputs =\n [contract_address.to_field(), rollup_version_id, recipient.to_field(), chain_id, content];\n for i in 0..inputs.len() {\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.push(item_bytes[j]);\n }\n }\n\n sha256_to_field(bytes.storage())\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) -> std::hash::poseidon2::Poseidon2 {\n let two_pow_64 = 18446744073709551616;\n let iv: Field = (in_len as Field) * two_pow_64;\n let mut sponge = std::hash::poseidon2::Poseidon2::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: std::hash::poseidon2::Poseidon2,\n input: [Field; N],\n in_len: u32,\n skip_0_check: bool,\n) -> std::hash::poseidon2::Poseidon2 {\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: std::hash::poseidon2::Poseidon2,\n input: [Field; N],\n in_len: u32,\n variable: bool,\n shift: u32,\n) -> std::hash::poseidon2::Poseidon2 {\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 two_pow_64 = 18446744073709551616;\n let iv: Field = (in_len as Field) * two_pow_64;\n let mut sponge = std::hash::poseidon2::Poseidon2::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 two_pow_64 = 18446744073709551616;\n let empty_sponge = std::hash::poseidon2::Poseidon2::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 = std::hash::poseidon2::Poseidon2::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" }, "257": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.67.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.68.0/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" }, "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(crate) 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" }, - "310": { - "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.67.0/noir-projects/noir-protocol-circuits/crates/types/src/storage/map.nr", + "312": { + "path": "/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.68.0/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};\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" }, "51": { 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 ba15c5e8..642512b3 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.0+263736c0e20c482c","name":"SimpleLogging","functions":[{"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/9VZ227aQBBdsI2xiQmFP4jUt1ayCdc3pF7yHSiBL+gH+KEv7VeXFTv2YTypkJipykjRGs/6zNkz4931pufONjz99cJ1HNqB6xr12YW2vM0qRazSkmfvTnj274RndCc8Y0WePYGnb+l9S9z5nUvd+X3sOPFhn+gI/O5vQCzo79Bmoe2DXzExVSYMVgt/Uy5eM3dpyvyfs4CZ2uAvCX9og18S7y91i49jobhRaF/qVssXeMZbEa6xiAmXfH3wfWW+CHzfmA9r+DvzYd0TJ9JtAGNRrKuNdV5obCmMrfdO61yrHd4jrXNnWqMV5TxjfDh/4lNQn7rlM2C+GHwZ8yXgI/19+wT9eO5T6PcZ7vOajFy3hslPOUetLWoqNsA/2ULSneckri9jow91j0HPJ6aPxVqB+ljo7/WZvcOfrr2ltWssYnqiRqTZEPszXwa+uL6Mk4ffMcRBLOKRsP6fwu/H0A7gGXp+IsQfsPgXvIV7qBHHioR71N+/kx/D9cid6+cn9XfdeUpvU71aSHO2Hv66wc9s+B8JP7fBXxH+yAa/2cs8mODPS8IvbPhvCX9sUz/NXvLRhv+B8Ccm+IsDrbsfXGvN/BCup3Bfb+6uqmv2RBg/Z1yt9kRTxofrg+uv980ErhPBx3M4E+LMhDgSVqaI9aCI9fifjnGoiDVSxBorYmnmMVXE0tQrV8QqFLE0615TL8qjtE/ztgtteaNJ+zRF/Erap2l+u5PWVF+xoCGOL2H9fzCdRyY8qzmtOfSuUwyMXRjFvna9pviFwId454LvlkPZw3Jz3G6W29OWrFrNt00+C8aV38NvIpyPsb+09kv7PkWtS+m7fwy6eovBVzBfAj7iKH33j434X6M/xp8IPr7+X5vLqeuuhyM2bjzj2qmMuT3/k87mjeev5bXvJsXPXXe+/lfni6gP30vnAteJ4OP7k1yIkwtx7hGLn9Gjhr6uSae4bv1auVxv2n9w0VyUuMtzf8fiJ6z/r/Abx0btLXP+cb2vjs/74365f3tbvO6nDN9bH3T6A/vRhmkVHwAA","debug_symbols":"tdfRioQgFAbgd/HaC49aZq+yLIOVDYJYWC0s0buvDbO7w8zl8N8EJ06fIf7I2dngu+16CWmcFtZ+7CxOvVvDlEq1H5x1OcQYrpfH10ycD6tu/cvs0lkuq8sra5XkzKeBtVqUr8cQPWtrefCXRvPbaMxfYyWPT86sRsEVCq5RsEHBDQq2IJiEgMkEkyVMVjBZw+QKJtcw2cDkBibDMkiwDBIsgwTLIMEySLAMEiyD9F4Grbo3lm19oQ2ObnC0hdFS4GjC0RJHKxytcXSFo3FplLg0SlwaJSiNR6m+XA6ui/4+M41b6h9GqPV79k/T1Jyn3g9b9udc9T9SnYdYaa717RYvBZX/I2XKImWhHw==","brillig_names":["compute_note_hash_and_optionally_a_nullifier"]},{"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":{"5019202896831570965":{"error_kind":"string","string":"attempt to add with overflow"},"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/9VZzWocRxDu0c7M/knWWEpEIJBnmFmtvNqbQvAtJKc8wGR3Joj4L5ISEgh4X8MXH303+GKDwTcbfDC++GawwQ9it+ia/aa2drSyqv3TsPRMd/VXX1V1V/f2BGZeAleH7N0IMgeuTi9WMkWstEayyYhlRr1zddfVa9DfUjS6y/Rq4u+nw2FXsE+R/27XYfr0D2F6wE/bDuen2Ryf22LLhnvHOURjOh9+fdfWZXI+4unR3+m2wJ90WTsfMH+0wB/BktqYevyorDGf8XV6oGRTYhbnUPgJ7PiabYj0bRhINpCe9Q+/xD3n/1z/9dbk5rT4cTo9Ko6PA2aXxF8q58GMzoH5Hcf85e9r1w7Lw+Lo6r+HxycL2LGATc9rRraN80I5LFJ+tOXA1enFShYxG35wtc0Fjxo4BGocrkz4nFTGr3Jq7Ae/2iPbXvBHA8Lv+OFfEH7XC/6w8k/PD//KP30//q/4r/vhPyb8DT/4e4R/yY9/KvxNP/gp4Sd+/FOdQS97wR9U/Lf8+KfKb9t+/FPS+eMbMy+0D5Hub6Fd77yajVc536D+HuOqyyfNAqaP+HD/0H5OvtsRuCZCH8/BO4KeHUGPhLWtiHVJEaujiLWliLWhiNVWxLqsiLWuiKUZx1gRS9P3mnMiUcTqf6E2RopYmvN+UxFLMxf2FLFailiaeYLWdtM9hvQf8HOcI0h/zyz61Mc5IhL82hL8Kv2HVfTPfsDwkU8s+Idi2Rb6CIv2hwiwUD4GG1Een2k8tv3l6kTADBmHtlm0B9vIv5bLn+55U8DiaysUcEMBd5V7PRwXLKmNab7XSxo4+75j97t2598IfM19ioP0XcDq/B/a6WdMfV7j2Bj6Uf4OYN52z5tMBmMo3Zv7WPPEvWWa57J0z6X5rakpJ6IPSP9F78W/5HyfmMU1xXObhBWdE+tzxhR9zc/sUt6W8h6dXVuzRSzqC6EvYn3RbNEndp95zPisGjdp76Cxnn094PkJuWLsSb89433vnqtvHVevH578dqO4MTn679ZJMf355h+GFf5Jg2/jUiqTPoOsmTpVorTqJx1piUvF/lVaJc36Ccs8zUrHIdw22tCP8nddbd+fMfulZSJdQ3EOKI9282mMS7TTMA6XgvS5woc/u+AvyZ/ob5S/52r0p5RGArDHlnDmxZ6x5fEceHB/RoyTFEMpFXE/oTzGhm8TeAXJ07KUWlAf/wtA4+Ml8niUQvn7rrY83zJ+0hF3owEbj3A+YznaT1PSSfMoMvXYGKY/YvIP3TteCxiw++AjeZajPCt38zLfy6fT4STfYvgGfNf3oP/3Iit2y7LcLfJheaU8Uz+1t2fz/hbz1an/3DOt3w7Ks74u9IWzuv6eew9BD2IRj4jJP3XvdL0Uwxganwj6Y6a/xltow3nNsVpCG/6tfeKefcS12B9P03FZ5FmWDaZpcVZcJT9hzrWFfI2xiAXbIib/Amx+6Z75MQ/1Wbk3DXLBkvoUQ2gLZ/U2KUY4d0medPdmixyprw99uB/Ysu7e0V+IRTwiJv/avVNMcL7R+ETQ32H6a7yFNj53+4J8X5C38XlFeK5G27X/np3qZPjYxrm9Ie5Gf10N9/LRJB9l2XiYFcNs76x19R5zvoS93CsAAA==","debug_symbols":"zZvRbuIwEEX/Jc958Njj8Ux/ZbWqaJtWSAgqSldaVfz7JmyTthsE6hVm56Ui1Zg5wPE1Tshb89DdvT7dLtePm5fm5sdbs9rcL3bLzbo/etu3zd12uVotn24//7sJwx+Kh/qX58V6OHzZLba75obEQtt064f+YQmhf4bH5aprbiTuf7YNJWAMA2MyMEaAMQUYo8AY+/6YGIAxBIwBPIiAB/G7HrTz4hDyWBxinoqp0JFqTqrv1ZysfFRHPVKtlMbnVsr0pXqgzxeg1zgW9/hXpZcL0DNN772ce+8pp5GesvEZeotxfG6LwjP6clF6Cl/phw5avYPV7pCAvEhAXiQgLxKQFwlYNxKwbiRg3UjAupGAdSMB6wYDHjDgAQMeMOABAx4w4AEDHjDgAQMeMOBBBjzIgAcZ8CADHmTAgwx4kAEPMuBBBjzIgAcCeCCABwJ4IIAHAngggAcCeCCABwJ4IIAHBfCgAB4UwIMCeFAADwrgQQE8KIAHBfCgAB4o4IECHijggQIeKOCBAh4o4IECHijggQIeGOCBAR4Y4IEBHhjggQEeGOCBAR4Y4IEd9yDl6cRD0jO7TC3jJlNN9qf37SnRWNw//Dij0W/nD2e9QvCFQ75woi+c5AuHfeFkXzjiC6f4wlFfOL5SmXylMvlKZfKVyuQrlclXKpOvVCZfqUy+Upl8pXK8tsrTFbGU2OY41/6whCeckuY4l/yw7PPVqr/X9Cha5QYp1G5AtRvE2g1S7QZcu0Gu3UBqNyi1G9Seyan2TObaM5lrz2SuPZO59kzm2jOZa89kvsBMzmFqoGcWWOM4FXOWOU7xhaO+cMwVTg6+cI7nFbOMOCxyGueiPy+jnFx9l87X/mpfZMJRnuNkXzjiC6f4wlFfOOYKR4IvHPp/ODbfNMu1zx2e3sNL8oXDvnCyLxzxhePrdJSoLxxzhVOCLxzyheMrlYuvVC6+Urn4SuXiK5WLo1Te94e/Ftvl4m7Vvd9s+Pi6vv907+Hu93P3z22Iz9vNfffwuu2GGxI/7kUc8iuG1MbI/cscJgiptWQ2vOhwOAwtaR4O6VAb2hhiz9Bz/AE=","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":"txs_effects_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":"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":"txs_effects_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"}}]}}]}}]}}]},"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":"7ZbdisIwEIXfJde9yMzkb3yVZZGqVQqllVoXFvHdNylNq25YWcsuCN6UTvNN5uRMEnoSm2J13C3LetscxOLtJKpmnXdlU/voJID6b4d9Xofw0OVtJxZgWGaiqDf+1Up5zsS2rAqxMHjOvsHoyA0wOjPBQDJBkwYeaNKMd2jHVg+0Y8cjjUgJGqyjKNvJaW40KViiibC0+hJ+zwSoly9JX/TLl6Qv5uVL0hc72xclddSuJMO0UpR9BffnFXh2Bd8VFWGiyX+wkKCZNQw0s3FXehL7BsnFyREV0K1+lE+uH1L6GXHcdlL/LN+StgNsyV0cFkzJ1y4aY2CaGJTuxeB8MRxhq8jeEQMMKmr370bNdpOefQHqvxdgzXhSmNXN/eCjVVtWVblbXv1ZyfBQyd0CIOP5AEB3u8UUPZKkHknSjySZXyf5CAKbvon01A19cbXokOjDj7wt81VVBFfD6LFeR5N92H3u40hsw75t1sXm2BahIVMvgqskMyXDlR6EKJdpGrX1n5AydL6qr/wF","brillig_names":["pack_arguments_oracle_wrapper","enqueue_public_function_call_internal"]},{"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/9VUyw6CMBBseURBOaiJ3kz8gyIYOJJ49x8akKMe8OKNT5eabbqpVRKlJkzSbEs3szNlW0oUKESPvAH9tGnIFdhBDCA6aN/tRgFr9hviQKs7JH/O0iQw+BtQ/5OfWtIvIPktnT+bAM+xVfzYi6w77UaIesKWZ/nPbHpe9fhc/MFnh32k1caghm+uIYci3RuYR4Y8iRlRd9prh/eV5YzJei7w++RVO67va/lrWIeafvmOFV/qrDMe1wmv+YFXVVrypcYv4KBzGnMvbGHe1wvY45yo3mjul/J0vZ0b0gNB8gCVxsvQjgYAAA==","debug_symbols":"nZJLCoMwFEX38sYOzM/fVqRI1CiBkEiMhSLuvVFsscVJMnlwwz13krNCL9plbKQezAxVvYIyHXfSaJ/WLYHWSqXk2FyfId0PQkd/nrje4+y4dVARnIDQPVQ09fQglYAqw9sjAYQD+ySwTwP7LKyPb/dLUmYnUVJMvgxi9IBYDJTFQHkMVERA5PbjS1qwD8RS+gttPj65lbxV4hRrWHR38cy9JvGn3GRNJ/rFil2+i3f+1ihPMPazfvoN","brillig_names":["sync_notes"]},{"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":"7Z3bbuM4DIbfJde5kEgd51UGi6LtdIoAQVv0sMCi6LuvY9ROasoWxEkWXZM3RdLot8RPDPPLceT3za+7m7f7q93D78eXzY+f75v94+316+7xoXv2/rHd3Dzv9vvd/dXpvzfm8MdC3/7l6frh8PTl9fr5dfPDhmy2m7uHX93DaEx3hN+7/d3mR4CPv7YbiwyNY2g8QxMYmsjQJIYmt2vAMDSWoWHkATDyAFrzYEsbG+OHxgb82NhGW2jtMKXP1g5zPLaGVGidLA7HTtbbL60Po/dnGH2CoXE3/P909OEMo3d2ZB9q7K3HYfTWZ1cZfQYYjp0hODL6eNbRW/N19Ice0sV7yJfuAc0f9+C8xyHnfLC1nAMz5HMCG6ezhvbPx3PO9wAy6hwy6hwyPu+wXF1swHHCE0w1gaGJDE1iaHK7xhmGxjI0wNAgQ+MYGkYeOEYeOEYeOEYeOEYeeEYeeEYe+Hoe5FypyNYdG4d0rDg2FFpHsOGzdQSsVbOuSMShtXGh0rrzFnEciskmTKufr2YwnHykfBIqZzDY0YQBuqnGMzSBoYkMTWJocrsmGIbGMjTA0CBDw8iDwMiDwMiDwMiDwMiDUM8DD5VqgTC8ozungrVqEcLg9mJIWKsWbnwjR29rfrurEF+WIjitFqk84waPy690YkANljpJQ7Wz+Vga0Zq+A3/pDsKlO4iX7iBduoN84Q6yuXQH9tIdwKU7wDN04IcO4OSswqGD0pptdCwJ8nGNBFA6Mo5HdnBcskCpXAGYoVx1i/m83NjjMAh/Umi7pgciTolMiHglMiESlMiESFQiEyJJiUyIZCXylUj3fYIimSKximSKBBTJFIn6VoLEKZIpEnWuBIlaV4JEvStBItO8huH8qD/5MmVAItO9LiGxMt3rIhKR7jWMbcPXpj0Ske51GYlI97qMxCmSKRKR7nUZiUj3uoxEpHtdRiLSvS4jEeleF5GASPe6jETdK0Gi7pUgUfdKkDhFMkUiwL32cQqwpH2cAnxmH6cA89jHKcARHuJEATavj1OAd+vjFGDI+jgFuKw+TickTiF+CIX4IRTih1CIH0IhfsgJ8UNOiB9yQvyQE+KHnBA/5NdTh9wxzpPfYA5xriZvI4yjiI7fuIeymiRvgWJDHPfgCIlcO+RXs0I4J5TVLCfOCWU1a49zQlnNQqUJSkzjDhrJ0E+f1axqzgglrMZ6nBPKatZL54SymsXVOaGIdLQ1KE6hUCgyHW0FikxHW4Ei09FWoKijLUBRR0uhRHW0BSjqaAtQ1NEWoKijLUBxCoVCkelos81DfBkpFJmOtgJFpqOtQJnbw3k8sftlI/ciFEjj120nYRZ3PI04HDe6k8Paz8HkbzSYZL7TYOx3Gsxqqgva4cCAYKfvjbSaglGJczWr2kqcq1moLseZV7P2rMS5muVkJc7VrBArcc4s+ka3Y030Fbfzf7xaKecRiiUGbW73Y9lQZu6K4kY7ZH0SByUoFAolKhQKJSkUCmVm8RmP98XI0gotzGx068Y7EXUPpWUKzGx1KxyKUygUilcoFErZp/jxnJP1PoqDEhUKhZIUCoWSFQqBMrPxrXAoVqFQKKBQKBRUKBSKUygUilcoFIo62gIUdbQFKOpoC1DU0VIooI62AGXG0cbxEiefszgooFAoFFQoFIpTKBRK2bzh8bJJRHHnaGf2lhUOJSkUCiUrFAJlZotb4VCsQqFQQKFQKKhQKBSnUCgUr1AoFHW0BSjqaAtQZhytdyOUIO4k08y+w7KhzGxSLByKVSgUCigUCgUVCoXiFAqFopeMFqAEhUKhRIVCoSSFQqCsaGf35TjXc4eJ5TjXc4eJ5TjXc4eJxTjLm9pGNxw/ekMkRZuQ3dBNDrSX0C6J7ZLULsmNP3E+iOY22FsWWY4IOCLkiBxH5DmiwBFFjihxRJyMSJyMSJyMSJyMSJyMSJyMKO/Ps1hOylvdZDvsGJSRSMq7jCxLbLsE2iXYLnHNRSu3F+DcXoBzewHO7QW4/NPnJQka0y4pz34Y0jLHTCTQLsF2iWuX+HZJaJfEdklt9guS9tm37bNf/jHSsgTaJdguce0S3y4J7ZLYLkntkvbZh/bZh/bZh/bZh/bZh/aphPaphPaphMap/Oie/X39vLu+2d+9dIrDi28Pt6+7x4fPp6//PA2v3Dzv9vvd/dXT8+Pt3a+357ur/ePt4bWN+fzzEzFu0aduKP2bPdptDIcntn/NbhGx67Pr918=","brillig_names":["add_to_counter_public"]},{"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":"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":"7d3bbts4EAbgd/G1L8gZkkP2VRaLIEnTwoCRFEm6wKLou6/sjSQnpqNSogcS9N8EdcOxhp+owzim+Gvz9eHu5/eb3eO3p5fNl79+bfZP97evu6fH5tWv39vN3fNuv999vzn97405/LD22P7lx+3j4eXL6+3z6+aLDclsNw+PX5t/ijHNO3zb7R82XwL9/nu7sTQihkfEuBExfkRMGBEjI2LiiJhUHkNmRMyIcUAjxgGVjoPteWMvqW3sU+oaW7GZ1o5jfGvtOEnfmmKmdbTs31pH6+271ofs3fTsA1HbOAQ/kD2xaVsTe9e3diH33hJC+97Rhnetm+y5cvZCA9lL4LfGIn02DeshGT+nZMKckpHpyYjpBoIEMzTIYmxbU3JpYJCRte3hRzaaj4PMhcrZywRKJ3NKJs4pmTQ9mUjcnW148DwcXTtsXAxx4DxsjUndmxvL7uOZ2JuF528Xnj8tPH9eeP5u4fn7hecfFp6/aOefTJd/ovN84szySfPKJ+hf76Lp8/ED4y2k9uZXTJ87eTnmbhece43rnOtzD24gd298Ow68iUO5lyUydFIIvKbOujV11q+ps2FNna1R4ibfd3aoqqSm8Gzr/5h4oHV0XREavenfm4hzJ25j2vd2hvq0m88cjn2NK+prWk9fxayor3ZFfaUV9ZVX1Fe3or76FfU1rKivK7pvkhXdN8ly75ua7ONy74QO2S/33uaQffZuxXMb40+KLwqTC7trdtTbvqPeDBxQkbpaN1KyA63Zt3+BdKcHX/YvxWRsmzTZdNr4wM3g1uR24Nbk9uDW5A7g1uQWcGtyR3BrcidwK3InA25NbgtuTW5UlarcqCpVuR24NblRVapy56vKrp/+5HuY4J7OLeDW5I7g1uTOVpWhCwnvI8A9jdsaA29VbwtvVW+Ct6o3w1vV28Fb1dvDW9U7wFvVW+Ct6h3hreqN+lLV26K+1PVGfanrjfpS13vmE4iWgeiAOB1x5lOeloE487lUy0Cc+SStZSDOfPbXMhBnPq1sEYg089lty0Cc+SS7ZSDO/MkEy0BExVIB0QFxOiIqlgqIqFgqIKJiqYCIiqUCIiqW6YiMiqUCogPinyC6HtHTGWL2wkJC3dIN4ga2APE/xjuKX7gKSYcYIr4hX1U8QVxX3BmIK4tbiCuL5z/rk8idiyGI1xRniCuLO4gri3uIK4sHiCuLC8SVxSPElcUTxHXFLyzdCPHriVuIK4uj5tQWR82pLe4griyOmlNbHDWntjhqTm3xfM2ZbLumoU0M8ariCeK64heWT4b49cRrLPrcLePc7KnwjuW4Cbr+Jvj6m3DTN5EkdptIg6vVhm5FWS/mZCV5kf8Tmv5lajLdECXDdiAh533b2vlw0jq7fG4kQ92AtvKu9TH9UCH9/vtshoeOR2u4PXqtETr3lBo7WPqE3PkYitffRLr6JiosA9sMn3Zox6HjwHFsjxrHSYaGneX2jB6bD9TOhl2FdV19d1wG64eSJ2u7MzWHgeSbi1v71om9P08e8yf+5IrH/VmNyX684s199cxlIGL+RAVEzJ+ogIj5E9MR576e6TIQMeO7AmK+WDRdEdvcu3t8AlA2YyWlTtyezVjJL/AK8SuKu6y4dR1i82EvxGuKe4griweIK4sLxJXF8/WbFerEE66cNcXzi2I2Q7z7ZNcZjPGq4gRxZXGGuLK4g7iyeP5+3HOH6L1AvKZ4gLiyuEBcWTxCXFk8QVxVnPLLZUL8iuIW4sriBHFlcYa4sriDuLI4ak5tcdSc2uKoObXFUXNqi6PmVBa3F2pO6WZl+YRFBquKW4grixPElcUZ4sri+QqI+9m1zPg7Z1XxAHFlcYG4sniEuLJ4griu+IUVMSF+PXELcWVxgriyOENcWdxBXFkcNae2OGpObfELNad3nXjAXySqikeIK4sniOuKX1jTFOLXE7cQVxYniCuLM8SVxR1mFyqLe4griweIK4sLxJXF8aDB6YgODxqsgIgHDVZAJCBORsyvAiOufX/x5mNIfomH5NrNpHC2lfwaBZ+HUHkIl4e4wkcnHoP8mKAwJkjGBMUxQWlE0IXnyA8E2TFBNCaIxwSNGREyZkTImBEhY0aEjBkRMmZE5J+g++npJP+82NQ9dT/xeYgvDwnlIVIeEstDUvFJK5WfgFP5CTiVn4BT+Qk4/+Smz0N8eUh+74d2WCZJZyFSHhLLQ1JpCOefH/F5iC0PofKQob2fCSne+2x8eUgoD5HykFgeUnzsszXlIbY8hMpDuDykfO/b8r1vy/e+Ld/7tnzvU/mupPJdSeW7kgp35e/m1T+3z7vbu/3DSxNx+OXPx/vX3dPj28vXf3+0v7l73u33u+83P56f7h++/nx+uNk/3R9+tzFvP/5i9tumwmlSOY52cn5L3hxeHrrPlLbMttlqs+X/AA==","brillig_names":["constructor"]},{"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":"H4sIAAAAAAAA/9VaP28jRRTfjb22187aji/JISFRIBq6Xcc+J53haGgoEIKGZok3xwlIpCTUmIIWiZKeho9xBaKBCokvQUFJh8gc8+xffn47dpIdC0ayZnfem/f/vfmzDoN/W2h/ptVhjJuMTW2fPqxlFdJKQ5Yz3FCZUBmb2IfYvu8AvFahAWJFlqroH6ejcRys6lyh/EexpenTPkLTA/20aek8nS/psy6mJcHtJME5rZvfLuCZ9g7Qkzk+bXXj65FnW2WPgnL7GBv8bJ+NLbr2+Vlx/fbnF6efvfflF58Ul5xpKKk2js1QHSypPr04v77MT6/fms0ui6srpuDKe6baBqqf5s/P350xteh+1D4sLq+eX5wztcaG1MSfTRib2j59WMsknlskG/LF2lRlzdDqLkcC8m+TrFXHdUj8RB62j8S92K6tyNpXYE14RhjyaSt8NFrsI7ThtBp7pEmwag/mizJV6IvRprEh/NuB11jNXD5D+3BsdBRZ+wospOeOwqej8NkWrV5QHuv3jWec394yn1iZN7V9erc25AH2vfBGvrswXmGcjjfNG+HfDlZ97iNvdkmeshgU2yWKrH0FxrGeKHwShc//ida2cyNR5oUlvfDhMdfaFZM+KAPXHm0tjh18Ogof1zp2X300mV15f1c+nutEqtlrl/RIKtSjSzjTivXAfOkS754fGy7OvH0/9IdCf88P/cXeH89xEgPmbPIBjJufnH6iYJmLOLcPcMT/Cmh+ZJ97yvykhB+e4RC/W8LvY9uL/Rp+7JcOgG5AvDzfh5yJ7yS2sQkM45JrO8YU10nUi2vbI4Chv7jxyR1tYc5SvwJdxpOmxQivhZGih8Aaih7aeuSq7RHBsF66fG3a1Pbpw1qm1TjkhbKYViPZAwW/peCjvaQOaD7guwKsC5ps+CzvdWW+ltOCf217w/uV8LbcyAPjLlHGBDdWeFdZuzdZJ5F/m2StutZzTUX7oX3Ed8b/EutX1xeX+bPi/SKfsTsjRSWEY2PXyxi/79B7SO9NhY6rhQpdl+qhIpe23HGKoO4y15iQl6evbW/S7YV99rxUDUU+Ke1lS3gD4Ij/je1N+r0a3raTVnq06zKWAfFRb8HXSvyAYFqJ7xEul05cxuoKba0MCf63thd/7cMc31uLfdJhADpoduyRDoL/o+0N7ndkM5zPSy3KxEstbgvYDyh3QvY7DLzY70hs9BhsUFNkPSQbCf73tsd4F9lr8+V83AKYVp970Wdk5HgN5DCPB8GyRcAX9QqCpd6Izzn5WMFH34jN+oTP+YnvSAttvkf4YsNGCT5vLwT/B9sb28h9sba9OyDZcXs3IFhH4attv/ZB5hf22W8Nz4a8Pcembc95y495yFv+A4Dxlh/j4K5bfrHFXbf8VdShhPj9V/JW/GAa5y3maE3B57x15TnuUfrBqi85vjFn9gm2ac7sEQzjRXyDOeOqGTsKXVfN2FF045rxk+2xZiSO+XgN4jNWJsfL/61InMqaxa0OcMT/xb6jH6WvP0DOs0menR3lZ/k4n81GpznvTQKwnYkF/AuA7ysY/jReMf3F3048fXI+ktjDNRRj+zcYRxjuZ3BuC+CI/wfQ/N0+a/vrkGCufTnbHGFoL9lje/47wcj12UJ4e/rMtfFnN+HfDlZrro/jvvbpF89rW/rcMBJ5tM9g2ucpU++7warPUD6hhWc41xUg/32isaFttPWxQTD0Ma+r2vWlwDBGmgRDvSSfOiW61Ug3sUNZneBzvuD/aXsDH1ilNH5cJzCnuU5wjCMMfct1IqF5U/uePqwtYrG7xkYJ2Ujw/7K9dheixbf2uZJlQHzUOyJ7YfzzZ66uH3stztK9NfbiOxPB/9thL01/LQdZBsTvOuyFtsS5zLustmwrFtfZlmNR8BvWnuvuKWLQx7T63Is+Y+28g3/9iIBvWb4g/ib+1/KlT/job61mcz3X7nm1ms31HGu21Daspa61B/3NfxWMgdZd6vkhxAefd9btOas+R6TD2emTYnhz1Jk8yYYns3XniKr5F8cns/TkrMizLBvO0mId/0WOzZdwzCnTmvZd7mAZX+hFhP+6JWDs/QblbaTwM3hHDrywpH9JQxmrz2+PxfNV/Np8FV94t+erMgqsAzDMd9N27TvaC2mJHBHhp7AXMa0Fc2R+X+HfIv635FbG+BNuR8HvKPjGP2/aSRK3qHvVe/uXPIk+jrFsEjs+8mo0zien+STLTkZZMcrG6/LqH4TSAIJsNAAA","debug_symbols":"7d3bbuo6EAbgd+GaC4/P7qssLVU9sCokBBVtt7RV9d13gnAItUlwBm2ly/9NVVpPMnxOgich8efiefX48XK/3v7ZvS3ufn0uNrunh/f1btu8+vxaLh73681m/XLf//NCtD9IHdq/vT5s25dv7w/798Ud2SCWi9X2ufnVCdEs4c96s1rcWfm1TBp74Y9tvbRdU5K5tkaaY1tjToslo75+Lxek+bmYEHPxNJKLVrGttj7JxbBzCcIe2wYpRnKxIrrYvuExF8vPReuYi3Fjufi43P5iYy4um4sJMuZiiYZzIaHimyXhzWkNQuVa+6hI4dRLisQhGz+rbMKcspFiVtnQrLKRs8pGzSobPatszKyysbPK5n8/FpuYjRTyLJvMJ7HUqhsWhFMaUuaWrLol695nZftRmDSVUlDMQlIYbmxUTMIo3W/a8nnwcfgC+Bh8SoCPw0fg4/BJ8HH4FPg4fBp8HD4DPg6fBR+HD1UHiw9VB4sPVQeHT6PqYPGh6mDxoeoY5bMu8vUuSh35UHWw+DT4OHyoOsb4bNfWnjdt+VB1sPhQdbD4UHWw+FB1cPgMqg4WH6oOFh+qDhYfqg4WnwYfhw9VB4sPVQeLD1UHiw9VB4sPVUdiYlFKpCaoD1ITDPpTE4zkUxMNk8QEY+7UBAPp1ASj49QEQ97UBOPYxMRhHJuaYBybmmAcm5pgHJuaaJgkJhjHpiYYx6YmGMemJhjHJia+0mOsPpkY+d2kzn3HyS4Lp6c3bgHr3NFKAMm67kk31n//Xqqvs7q8HWCosxS9IWCddesNAesscosAnY9ZkBffP4VDnRXxDQE1AHmAddbaNwSsszC/ISAqESYgKhEmICoRHiAJlCJcQdQiXEEUI1xBVCNcQQ1BpiDqEa4gChKuICoSriBKEq4gapJRwUBxIggKKhEk1CRcQdQkXMEb1CRkuyswktyIoPTdNf8wsmCnuulCdG+xdMxc/djM9Y/N3PzYzMfHnNKPZH6aSoesEmeryGROIU5edPaFn/zMOBRc90aFGmvtKCbizuYXyuWhO0HTO2K1bQ8srlYWEd+hkSFl8WDJsQSwZFiumA+pShYCS45FgiXHov4mFtGNRWwYY2nG8N3IvzcVE/mQLVecOpUrve8RC5crQbqxv+8/Mjfb1lLM2Sp71vbQPRrdM+fuMeieOXdPnefKFMUFSyXp+6mHSuepGkGp84zWCEqdF85HUOq8Fj6CooGSotR5xXoEJX9CUHSn1puxghlew99/f14InSAllw4uTNcEwesF86cZSXdnyMl4CA4JBgjyBC/M2wTB6wUJgkzB/PieXIdCAZ8kg4L5IZ4Wcdad5ldsg4OCFoJMQQdBpqCHIFPwwonW7rshZIyD4IDgpRl1IHi1IEGQKSghyBRUEGQKaggyBQ0EmYIWgkxBB0GmoIcgUxA1CVPQoibhCqIm4QqiJuEKoibhCuq8oOvu8DMhQHBI0ECQKWghyBR0EGQK5kfU6nSns1K4TjIkeGGSIAheL0gQZApKCDIFFQSZghqCTEEDQaaghSBT0EGQKeghyBRETcIU9KhJuIIXahKjO0GLM6yDghKCTEEFQaaghiBT0ECQKWghyBR0EGQK4m4IrmCAIE/wwgyWELxekCDIFKzzQS8jKBooKUqdD3oZQalztpFBFJl/cL7TcfnOiCQku8cFHVcTbLoWUx5iy0NceYgvfHTNIShMCLrwbOCRIJoSJKcEqSlBekqQmRJkpwS5KUFTtgg5ZYtQU7YINWWLUFO2CDVli8g/YWzwcJJ//lag+JzQoNKQUBySf7rNcAiVh8jyEFV80NLlB2BdfgDW5QdgXX4Azj/pYDgkFIfk72UPNm6WwYUkhMpDZHmIKg/R5SGmPMSWh4z1fiakvPdNee/n7xoaDqHyEFkeUr7v2/J935bv+7Z837fl+74t731b3vuuvPddee+78t535V3pyrvSlXelK+zKr+bVPw/79cPjZvXWRLT//Ng+va932+PL939f438e9+vNZv1y/7rfPa2eP/ar+83uqf3fQhx//JLeLpVwv9u55ZqX1BQwUuj2ZdsvSvhlU0M1a23W/B8=","brillig_names":["get_counter_value"]}],"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::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::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(crate) 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"},"103":{"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\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.67.0/noir-projects/aztec-nr/aztec/src/state_vars/map.nr"},"116":{"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\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.67.0/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr"},"120":{"source":"use dep::protocol_types::debug_log::debug_log_format;\n\nuse crate::{\n context::{inputs::PrivateContextInputs, packed_returns::PackedReturns},\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 arguments,\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 key_validation_request::get_key_validation_request,\n returns::pack_returns,\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 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 self.nullifiers.push(\n Nullifier {\n value: nullifier,\n note_hash: nullified_note_hash,\n counter: self.next_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 pack_returns(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 let request = unsafe { get_key_validation_request(pk_m_hash, key_index) };\n assert(request.pk_m.hash() == pk_m_hash);\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 ) -> PackedReturns {\n let args_hash = hash_args_array(args);\n arguments::pack_arguments_array(args);\n self.call_private_function_with_packed_args(\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 ) -> PackedReturns {\n let args_hash = hash_args_array(args);\n arguments::pack_arguments_array(args);\n self.call_private_function_with_packed_args(\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 ) -> PackedReturns {\n self.call_private_function_with_packed_args(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 ) -> PackedReturns {\n self.call_private_function_with_packed_args(contract_address, function_selector, 0, true)\n }\n\n pub fn call_private_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field,\n is_static_call: bool,\n ) -> PackedReturns {\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 // The oracle simulates the private call and returns the value of the side effects counter after execution of\n // the call (which means that end_side_effect_counter - start_side_effect_counter is the number of side effects\n // that took place), along with the hash of the return values. We validate these by requesting a private kernel\n // iteration in which the return values are constrained to hash to `returns_hash` and the side effects counter\n // 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 PackedReturns::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 arguments::pack_arguments_array(args);\n self.call_public_function_with_packed_args(\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 arguments::pack_arguments_array(args);\n self.call_public_function_with_packed_args(\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_packed_args(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_packed_args(contract_address, function_selector, 0, true)\n }\n\n pub fn call_public_function_with_packed_args(\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 // TODO(https://github.com/AztecProtocol/aztec-packages/issues/8985): Fix this.\n // WARNING: This is insecure and should be temporary!\n // The oracle repacks 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 = enqueue_public_function_call_internal(\n contract_address,\n function_selector,\n args_hash,\n counter,\n is_static_call,\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 arguments::pack_arguments_array(args);\n self.set_public_teardown_function_with_packed_args(\n contract_address,\n function_selector,\n args_hash,\n false,\n )\n }\n\n pub fn set_public_teardown_function_with_packed_args(\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 // TODO(https://github.com/AztecProtocol/aztec-packages/issues/8985): Fix this.\n // WARNING: This is insecure and should be temporary!\n // The oracle repacks 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 = set_public_teardown_function_call_internal(\n contract_address,\n function_selector,\n args_hash,\n counter,\n is_static_call,\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.67.0/noir-projects/aztec-nr/aztec/src/context/private_context.nr"},"121":{"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::arguments::pack_arguments;\n\npub trait CallInterface {\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 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 pack_arguments(self.args);\n let returns = context.call_private_function_with_packed_args(\n self.target_contract,\n self.selector,\n self.args_hash,\n false,\n );\n let unpacked: T = returns.unpack_into();\n unpacked\n }\n\n pub fn view(self, context: &mut PrivateContext) -> T\n where\n T: Deserialize,\n {\n pack_arguments(self.args);\n let returns = context.call_private_function_with_packed_args(\n self.target_contract,\n self.selector,\n self.args_hash,\n true,\n );\n returns.unpack_into()\n }\n}\n\nimpl CallInterface for PrivateVoidCallInterface {}\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 pack_arguments(self.args);\n context\n .call_private_function_with_packed_args(\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 pack_arguments(self.args);\n context\n .call_private_function_with_packed_args(\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\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 pack_arguments(self.args);\n let returns = context.call_private_function_with_packed_args(\n self.target_contract,\n self.selector,\n self.args_hash,\n true,\n );\n returns.unpack_into()\n }\n}\n\nimpl CallInterface for PrivateStaticVoidCallInterface {}\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 pack_arguments(self.args);\n context\n .call_private_function_with_packed_args(\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\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 pack_arguments(self.args);\n context.call_public_function_with_packed_args(\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 pack_arguments(self.args);\n context.call_public_function_with_packed_args(\n self.target_contract,\n self.selector,\n args_hash,\n /*static=*/\n true,\n )\n }\n}\n\nimpl CallInterface for PublicVoidCallInterface {}\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 pack_arguments(self.args);\n context.call_public_function_with_packed_args(\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 pack_arguments(self.args);\n context.call_public_function_with_packed_args(\n self.target_contract,\n self.selector,\n args_hash,\n /*static=*/\n true,\n )\n }\n}\n\nimpl CallInterface for PublicStaticCallInterface {}\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 pack_arguments(self.args);\n context.call_public_function_with_packed_args(\n self.target_contract,\n self.selector,\n args_hash,\n /*static=*/\n true,\n )\n }\n}\n\nimpl CallInterface for PublicStaticVoidCallInterface {}\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 pack_arguments(self.args);\n context.call_public_function_with_packed_args(\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.67.0/noir-projects/aztec-nr/aztec/src/context/call_interfaces.nr"},"122":{"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.67.0/noir-projects/aztec-nr/aztec/src/context/unconstrained_context.nr"},"128":{"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 // 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 // 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 // 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 // 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 // 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 // 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 // AVM opcodes are constrained by the AVM itself\n unsafe { emit_nullifier(nullifier) };\n }\n\n pub fn this_address(_self: Self) -> AztecAddress {\n // AVM opcodes are constrained by the AVM itself\n unsafe {\n address()\n }\n }\n pub fn msg_sender(_self: Self) -> AztecAddress {\n // 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 // 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 // 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 // AVM opcodes are constrained by the AVM itself\n unsafe {\n chain_id()\n }\n }\n pub fn version(_self: Self) -> Field {\n // AVM opcodes are constrained by the AVM itself\n unsafe {\n version()\n }\n }\n pub fn block_number(_self: Self) -> Field {\n // AVM opcodes are constrained by the AVM itself\n unsafe {\n block_number()\n }\n }\n pub fn timestamp(_self: Self) -> u64 {\n // 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 // 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 // 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 // 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 // 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 // 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 // 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 // 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.67.0/noir-projects/aztec-nr/aztec/src/context/public_context.nr"},"130":{"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.67.0/noir-projects/aztec-nr/aztec/src/hash.nr"},"145":{"source":"/// Notifies the simulator that `args` will later be used at some point during execution, referenced by their hash. This\n/// allows the simulator to know how to respond to this future request.\n///\n/// This is only used during private execution, since in public it is the VM itself that keeps track of arguments.\npub fn pack_arguments(args: [Field]) {\n // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe to call. When\n // unpacking however the caller must check that the returned value is indeed the preimage.\n unsafe { pack_arguments_oracle_wrapper(args) };\n}\n\n/// Same as `pack_arguments`, but using arrays instead of slices.\npub fn pack_arguments_array(args: [Field; N]) {\n // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe to call. When\n // unpacking however the caller must check that the returned value is indeed the preimage.\n unsafe { pack_arguments_array_oracle_wrapper(args) };\n}\n\nunconstrained fn pack_arguments_oracle_wrapper(args: [Field]) {\n let _ = pack_arguments_oracle(args);\n}\n\nunconstrained fn pack_arguments_array_oracle_wrapper(args: [Field; N]) {\n let _ = pack_arguments_array_oracle(args);\n}\n\n#[oracle(packArguments)]\nunconstrained fn pack_arguments_oracle(_args: [Field]) -> Field {}\n\n#[oracle(packArgumentsArray)]\nunconstrained fn pack_arguments_array_oracle(_args: [Field; N]) -> Field {}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.67.0/noir-projects/aztec-nr/aztec/src/oracle/arguments.nr"},"146":{"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 let instance =\n unsafe { ContractInstance::deserialize(get_contract_instance_internal(address)) };\n // The to_address function combines all values in the instance object to produce an address, so by checking that we\n // get the expected address we validate the entire struct.\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 let (member, exists) = 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 let (member, exists) = 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 let (member, exists) = 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.67.0/noir-projects/aztec-nr/aztec/src/oracle/get_contract_instance.nr"},"153":{"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.67.0/noir-projects/aztec-nr/aztec/src/oracle/execution.nr"},"154":{"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 // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe 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 // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe to call.\n unsafe { notify_nullified_note_oracle_wrapper(nullifier, note_hash, counter) };\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\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_app_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_app_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 ivpsk_m of the sender.\n/// For the recipient's side, only the address is needed.\npub unconstrained fn get_app_tagging_secret_as_sender(\n sender: AztecAddress,\n recipient: AztecAddress,\n) -> IndexedTaggingSecret {\n let result = get_app_tagging_secret_as_sender_oracle(sender, recipient);\n IndexedTaggingSecret::deserialize(result)\n}\n\n#[oracle(getAppTaggingSecretAsSender)]\nunconstrained fn get_app_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 // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe 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 // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe 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.67.0/noir-projects/aztec-nr/aztec/src/oracle/notes.nr"},"155":{"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 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.67.0/noir-projects/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr"},"156":{"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.67.0/noir-projects/aztec-nr/aztec/src/oracle/storage.nr"},"171":{"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\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.67.0/noir-projects/aztec-nr/aztec/src/initializer.nr"},"177":{"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, 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::embedded_curve_ops::{EmbeddedCurveScalar, fixed_base_scalar_mul as derive_public_key};\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.67.0/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr"},"189":{"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.67.0/noir-projects/noir-protocol-circuits/crates/types/src/type_serialization.nr"},"207":{"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.67.0/noir-projects/noir-protocol-circuits/crates/types/src/utils/reader.nr"},"211":{"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\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 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: validate_array(array) should be true.\npub fn array_length(array: [T; N]) -> u32\nwhere\n T: Empty + Eq,\n{\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\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]\nfn find_index_greater_than_min() {\n let values = [10, 20, 30, 40];\n let min = 22;\n let index = unsafe { find_index_hint(values, |v: Field| min.lt(v)) };\n assert_eq(index, 2);\n}\n\n#[test]\nfn find_index_not_found() {\n let values = [10, 20, 30, 40];\n let min = 100;\n let index = unsafe { 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 concated = array_concat(array0, array1);\n assert_eq(concated, [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.67.0/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr"},"221":{"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.67.0/noir-projects/noir-protocol-circuits/crates/types/src/traits.nr"},"223":{"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::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 traits::{is_empty, ToField},\n utils::field::field_from_bytes_32_trunc,\n};\nuse super::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\nfn compute_note_hash_nonce(tx_hash: Field, note_index_in_tx: u32) -> Field {\n // Hashing tx hash with note index in tx is guaranteed to be unique\n poseidon2_hash_with_separator(\n [tx_hash, 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 tx_hash: 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(tx_hash, 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: BoundedVec = BoundedVec::new();\n\n let inputs =\n [contract_address.to_field(), rollup_version_id, recipient.to_field(), chain_id, content];\n for i in 0..inputs.len() {\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.push(item_bytes[j]);\n }\n }\n\n sha256_to_field(bytes.storage())\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\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 two_pow_64 = 18446744073709551616;\n let iv: Field = (in_len as Field) * two_pow_64;\n let mut sponge = std::hash::poseidon2::Poseidon2::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 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.67.0/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr"},"257":{"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.67.0/noir-projects/noir-protocol-circuits/crates/types/src/abis/function_selector.nr"},"310":{"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};\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.67.0/noir-projects/noir-protocol-circuits/crates/types/src/storage/map.nr"}}} \ No newline at end of file +{"noir_version":"1.0.0-beta.0+263736c0e20c482c","name":"SimpleLogging","functions":[{"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/9VZ227aQBBdsI2xiQmFP4jUt1ayCdc3pF7yHSiBL+gH+KEv7VeXFTv2YTypkJipykjRGs/6zNkz4931pufONjz99cJ1HNqB6xr12YW2vM0qRazSkmfvTnj274RndCc8Y0WePYGnb+l9S9z5nUvd+X3sOPFhn+gI/O5vQCzo79Bmoe2DXzExVSYMVgt/Uy5eM3dpyvyfs4CZ2uAvCX9og18S7y91i49jobhRaF/qVssXeMZbEa6xiAmXfH3wfWW+CHzfmA9r+DvzYd0TJ9JtAGNRrKuNdV5obCmMrfdO61yrHd4jrXNnWqMV5TxjfDh/4lNQn7rlM2C+GHwZ8yXgI/19+wT9eO5T6PcZ7vOajFy3hslPOUetLWoqNsA/2ULSneckri9jow91j0HPJ6aPxVqB+ljo7/WZvcOfrr2ltWssYnqiRqTZEPszXwa+uL6Mk4ffMcRBLOKRsP6fwu/H0A7gGXp+IsQfsPgXvIV7qBHHioR71N+/kx/D9cid6+cn9XfdeUpvU71aSHO2Hv66wc9s+B8JP7fBXxH+yAa/2cs8mODPS8IvbPhvCX9sUz/NXvLRhv+B8Ccm+IsDrbsfXGvN/BCup3Bfb+6uqmv2RBg/Z1yt9kRTxofrg+uv980ErhPBx3M4E+LMhDgSVqaI9aCI9fifjnGoiDVSxBorYmnmMVXE0tQrV8QqFLE0615TL8qjtE/ztgtteaNJ+zRF/Erap2l+u5PWVF+xoCGOL2H9fzCdRyY8qzmtOfSuUwyMXRjFvna9pviFwId454LvlkPZw3Jz3G6W29OWrFrNt00+C8aV38NvIpyPsb+09kv7PkWtS+m7fwy6eovBVzBfAj7iKH33j434X6M/xp8IPr7+X5vLqeuuhyM2bjzj2qmMuT3/k87mjeev5bXvJsXPXXe+/lfni6gP30vnAteJ4OP7k1yIkwtx7hGLn9Gjhr6uSae4bv1auVxv2n9w0VyUuMtzf8fiJ6z/r/Abx0btLXP+cb2vjs/74365f3tbvO6nDN9bH3T6A/vRhmkVHwAA","debug_symbols":"tdfRioQgFAbgd/HaC49aZq+yLIOVDYJYWC0s0buvDbO7w8zl8N8EJ06fIf7I2dngu+16CWmcFtZ+7CxOvVvDlEq1H5x1OcQYrpfH10ycD6tu/cvs0lkuq8sra5XkzKeBtVqUr8cQPWtrefCXRvPbaMxfYyWPT86sRsEVCq5RsEHBDQq2IJiEgMkEkyVMVjBZw+QKJtcw2cDkBibDMkiwDBIsgwTLIMEySLAMEiyD9F4Grbo3lm19oQ2ObnC0hdFS4GjC0RJHKxytcXSFo3FplLg0SlwaJSiNR6m+XA6ui/4+M41b6h9GqPV79k/T1Jyn3g9b9udc9T9SnYdYaa717RYvBZX/I2XKImWhHw==","brillig_names":["compute_note_hash_and_optionally_a_nullifier"]},{"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":"7d3bbts4EAbgd/F1LjjDw5B9lWIRJGlaGDCSIkkXWBR995XdSHJiOgoleiBB/01Q1xxr+ImSNbYp/t58u7/99eN6+/D98Xnz5evvze7x7uZl+/jQPPr952pz+7Td7bY/ro//e2P2f4gO7Z9/3jzsHz6/3Dy9bL5QSOZqc//wrfmnGNO8wvft7n7zJfCff642xCNi7IgYNyLGj4gJI2JkREwcEZPKY9iMiBkxDnjEOODScXB12thLahv7lLrGJJRp7WyMr62dTdK35phpHcn619aRPL1pvc/eTc8+MLeNQ/AD2bM1bWu23vWtXci9toTQvnak8KZ1k72tnL3wQPYS7GtjkT6bhnWfjJ9TMmFOycj0ZMR0A0GCGRpkMbatObk0MMiYqD38mKJ5P8hcqJy9TKB0Mqdk4pySSdOTiWy7s40dPA9H1w4bF0McOA+TMal7cUPWvT8Te7Pw/Gnh+fPC87cLz98tPH+/8PzDwvMX7fyT6fJPfJpPnFk+aV75BP33u2j6fPzAeAupvfgV0+fOXg6504Jzr/E+5/rcgxvI3RvfjgNv4lDuZYkMnRSCXVNn3Zo669fU2bCmztYocZPvOztUVXJTeLb1f0x2oHV0XREavelfm9nmTtzGtK/tDPdpN585HPoaV9TXtJ6+illRX2lFfeUV9dWuqK9uRX31K+prWFFfV3TdJCu6bpLlXjc12cflXgnts1/utc0+++zVirdtjD8qvjhMLuwu2VFPfUe9GTigIne1buREA62tb7+BdMcHX/abYjbUJs2UjhvvuS24NbkduDW5Pbg1uQO4NbkF3JrcEdya3AncitzJgFuTm8CtyY2qUpUbVaUqtwO3JjeqSlXufFXZ9dMf/Q4T3NO5Bdya3BHcmtzZqjJ0IeFtBLincZMx8Fb1JnirejO8Vb0tvFW9HbxVvT28Vb0DvFW9Bd6q3hHeqt6oL1W9CfWlrjfqS11v1Je63jOfQLQMRAfE6Ygzn/K0DMSZz6VaBuLMJ2ktA3Hms7+WgTjzaWWLQOSZz25bBuLMJ9ktA3HmdyZYBiIqlgqIDojTEVGxVEBExVIBERVLBURULBUQUbFMR7SoWCogOiB+BtH1iJ5PELNvLCzcLd0gbmALEP803kH8zLuQdIgh4hfyVcUTxHXFnYG4sjhBXFk8/1mfRNu5GIZ4TXELcWVxB3FlcQ9xZfEAcWVxgbiyeIS4sniCuK74maUbIX45cYK4sjhqTm1x1Jza4g7iyuKoObXFUXNqi6Pm1BbP15yJ2jUNKVmIVxVPENcVP7N8MsQvJ15j0eduGedmT4U3LIdN8OU3YS+/CTd9E0lit4k0uFpt6FaU9WKOVpIX+ZvQ9B9Ts+mGKBtLAwk579vWzoej1tnlcyMb7gY0yZvWh/RDhfT737MZO3Q8krHt0UtG+NRTauxg6RNyp2MoXn4T6eKbqLAMbDN82qEdh44DZ2N71DibZGjYkW3P6LH5QO1k2FVY19V3x2UgP5Q8E3VnahsGkm/e3NqXTtb70+Qxf+Iz73i2P6tZpvfveHNfPXMZiJg/UQER8ycqIGL+xHTEua9nugxEzPiugJgvFk1XxDbX7h6fAJTNWEmpE6eTGSv5BV4hfkFxlxUn1yE2H/ZCvKa4h7iyeIC4srhAXFk8X7+RcCee8M5ZUzy/KGYzxLtPdp3BGK8qzhBXFrcQVxZ3EFcWz1+Pe9shei8QrykeIK4sLhBXFo8QVxZPEFcV5/xymRC/oDhBXFmcIa4sbiGuLO4griyOmlNbHDWntjhqTm1x1Jza4qg5lcXpTM0p3awsn7DIYFVxgriyOENcWdxCXFk8XwHZfnattfies6p4gLiyuEBcWTxCXFk8QVxX/MyKmBC/nDhBXFmcIa4sbiGuLO4griyOmlNbHDWntviZmtO7TjzgG4mq4hHiyuIJ4rriZ9Y0hfjlxAniyuIMcWVxC3FlcYfZhcriHuLK4gHiyuICcWVx3GhwOqLDjQYrIOJGgxUQGYiTEfOrwIhrX1+8eR+SX+IhuXYzKZxsJb9GwcchXB5iy0Nc4a0TD0F+TFAYEyRjguKYoDQi6Mx95AeCaEwQjwmyY4LGjAgZMyJkzIiQMSNCxowIGTMi8nfQ/fB0kr9fbOruup/saYgvDwnlIVIeEstDUvFJK5WfgFP5CTiVn4BT+Qk4f+emj0N8eUh+74d2WCZJJyFSHhLLQ1JpiM3fP+LjECoP4fKQob2fCSne+9b48pBQHiLlIbE8pPjYt2TKQ6g8hMtDbHlI+d6n8r1P5Xufyvc+le99Lt+VXL4ruXxXcuGu/NM8+vfmaXtzu7t/biL2T/56uHvZPj68Pnz572f7zO3Tdrfb/rj++fR4d//t19P99e7xbv/cxrz++Wqtv2oqnCaVw2hn56/Ym/3Dffetl+bZ1Gy12fL/","brillig_names":["constructor"]},{"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/9VUyw6CMBBseURBOaiJ3kz8gyIYOJJ49x8akKMe8OKNT5eabbqpVRKlJkzSbEs3szNlW0oUKESPvAH9tGnIFdhBDCA6aN/tRgFr9hviQKs7JH/O0iQw+BtQ/5OfWtIvIPktnT+bAM+xVfzYi6w77UaIesKWZ/nPbHpe9fhc/MFnh32k1caghm+uIYci3RuYR4Y8iRlRd9prh/eV5YzJei7w++RVO67va/lrWIeafvmOFV/qrDMe1wmv+YFXVVrypcYv4KBzGnMvbGHe1wvY45yo3mjul/J0vZ0b0gNB8gCVxsvQjgYAAA==","debug_symbols":"nZLNCoQgFIXf5a5bpGk/vkoMYWUhiIbZwBC9+1g0QzO00c2FI+c7G78VetEuYyP1YGZg9QrKdNxJo31atwRaK5WSY3N9hnQ/CB39eeJ6j7Pj1gHLcAJC98BI6ulBKgEsx9sjAYQD+1lgnwT2aVgf3+5XBFUnURGSfxlEyQHRGCiPgYoYqIyAstuPr2hafiCKi19o8/HJreStEqdYw6K7i2fuNYk/5SZrOtEvVuzyXbzzt0ZFgrGf9dNv","brillig_names":["sync_notes"]},{"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":"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","brillig_names":["add_to_counter_public"]},{"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":"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":"7ZbtasIwFIbvJb/7I+crH97KGKNqJ4VSpepgiPe+RJpWXZxM2UDwT+lpnpPz5j1J6E7Nq+l28Va378u1mrzsVLOclZt62YZop4AO39arso3helN2GzUB43WhqnYeXq3W+0K9102lJgb3xTcYHbkeRmdGGEhnaBLwPU3i8QoNhmVQYtjwwCNSjreOEu70ODuaHKzRJFhbOYZfCwX8dOaCM/J05oIz5unMBWfs3c6wFulh1h7GtaI+VHB/XsHfXSH0hRNM5McKFjK09wI97b1xJ3oyOwfJpckRGehcP+oH1w85/R5x2HZafpZvSWwPW3JHxwVz8sUlYwyMEwPLQQzeL8Yn2DLZK2LAAyft4f3o7N7qJj36Avi/F2DNcFK857P7IUTTrm6aevF28oel44OzuwVAp/MBgO58izHdksS3JMktSebXSSGCyOZvIhm7IUdXi8TEEH6UXV1Omyq6Gke37SyZHMLN5yqNpDasuuWsmm+7KjZk7EV0lXTBOl7pUQi7QmjQdviEVKALVUPlLw==","brillig_names":["pack_arguments_oracle_wrapper","enqueue_public_function_call_internal"]},{"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":{"5019202896831570965":{"error_kind":"string","string":"attempt to add with overflow"},"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/9VZzWocRxDu0c7M/knWWEpEIJBnmFmtvNqbQvAtJKc8wGR3Joj4L5ISEgh4X8MXH303+GKDwTcbfDC++GawwQ9it+ia/aa2drSyqv3TsPRMd/VXX1V1V/f2BGZeAleH7N0IMgeuTi9WMkWstEayyYhlRr1zddfVa9DfUjS6y/Rq4u+nw2FXsE+R/27XYfr0D2F6wE/bDuen2Ryf22LLhnvHOURjOh9+fdfWZXI+4unR3+m2wJ90WTsfMH+0wB/BktqYevyorDGf8XV6oGRTYhbnUPgJ7PiabYj0bRhINpCe9Q+/xD3n/1z/9dbk5rT4cTo9Ko6PA2aXxF8q58GMzoH5Hcf85e9r1w7Lw+Lo6r+HxycL2LGATc9rRraN80I5LFJ+tOXA1enFShYxG35wtc0Fjxo4BGocrkz4nFTGr3Jq7Ae/2iPbXvBHA8Lv+OFfEH7XC/6w8k/PD//KP30//q/4r/vhPyb8DT/4e4R/yY9/KvxNP/gp4Sd+/FOdQS97wR9U/Lf8+KfKb9t+/FPS+eMbMy+0D5Hub6Fd77yajVc536D+HuOqyyfNAqaP+HD/0H5OvtsRuCZCH8/BO4KeHUGPhLWtiHVJEaujiLWliLWhiNVWxLqsiLWuiKUZx1gRS9P3mnMiUcTqf6E2RopYmvN+UxFLMxf2FLFailiaeYLWdtM9hvQf8HOcI0h/zyz61Mc5IhL82hL8Kv2HVfTPfsDwkU8s+Idi2Rb6CIv2hwiwUD4GG1Een2k8tv3l6kTADBmHtlm0B9vIv5bLn+55U8DiaysUcEMBd5V7PRwXLKmNab7XSxo4+75j97t2598IfM19ioP0XcDq/B/a6WdMfV7j2Bj6Uf4OYN52z5tMBmMo3Zv7WPPEvWWa57J0z6X5rakpJ6IPSP9F78W/5HyfmMU1xXObhBWdE+tzxhR9zc/sUt6W8h6dXVuzRSzqC6EvYn3RbNEndp95zPisGjdp76Cxnn094PkJuWLsSb89433vnqtvHVevH578dqO4MTn679ZJMf355h+GFf5Jg2/jUiqTPoOsmTpVorTqJx1piUvF/lVaJc36Ccs8zUrHIdw22tCP8nddbd+fMfulZSJdQ3EOKI9282mMS7TTMA6XgvS5woc/u+AvyZ/ob5S/52r0p5RGArDHlnDmxZ6x5fEceHB/RoyTFEMpFXE/oTzGhm8TeAXJ07KUWlAf/wtA4+Ml8niUQvn7rrY83zJ+0hF3owEbj3A+YznaT1PSSfMoMvXYGKY/YvIP3TteCxiw++AjeZajPCt38zLfy6fT4STfYvgGfNf3oP/3Iit2y7LcLfJheaU8Uz+1t2fz/hbz1an/3DOt3w7Ks74u9IWzuv6eew9BD2IRj4jJP3XvdL0Uwxganwj6Y6a/xltow3nNsVpCG/6tfeKefcS12B9P03FZ5FmWDaZpcVZcJT9hzrWFfI2xiAXbIib/Amx+6Z75MQ/1Wbk3DXLBkvoUQ2gLZ/U2KUY4d0medPdmixyprw99uB/Ysu7e0V+IRTwiJv/avVNMcL7R+ETQ32H6a7yFNj53+4J8X5C38XlFeK5G27X/np3qZPjYxrm9Ie5Gf10N9/LRJB9l2XiYFcNs76x19R5zvoS93CsAAA==","debug_symbols":"zZvRbuIwEEX/Jc958Njj8Ux/ZbWqaJtWSAgqSldaVfz7JmyTthsE6hVm56Ui1Zg5wPE1Tshb89DdvT7dLtePm5fm5sdbs9rcL3bLzbo/etu3zd12uVotn24//7sJwx+Kh/qX58V6OHzZLba75obEQtt064f+YQmhf4bH5aprbiTuf7YNJWAMA2MyMEaAMQUYo8AY+/6YGIAxBIwBPIiAB/G7HrTz4hDyWBxinoqp0JFqTqrv1ZysfFRHPVKtlMbnVsr0pXqgzxeg1zgW9/hXpZcL0DNN772ce+8pp5GesvEZeotxfG6LwjP6clF6Cl/phw5avYPV7pCAvEhAXiQgLxKQFwlYNxKwbiRg3UjAupGAdSMB6wYDHjDgAQMeMOABAx4w4AEDHjDgAQMeMOBBBjzIgAcZ8CADHmTAgwx4kAEPMuBBBjzIgAcCeCCABwJ4IIAHAngggAcCeCCABwJ4IIAHBfCgAB4UwIMCeFAADwrgQQE8KIAHBfCgAB4o4IECHijggQIeKOCBAh4o4IECHijggQIeGOCBAR4Y4IEBHhjggQEeGOCBAR4Y4IEd9yDl6cRD0jO7TC3jJlNN9qf37SnRWNw//Dij0W/nD2e9QvCFQ75woi+c5AuHfeFkXzjiC6f4wlFfOL5SmXylMvlKZfKVyuQrlclXKpOvVCZfqUy+Upl8pXK8tsrTFbGU2OY41/6whCeckuY4l/yw7PPVqr/X9Cha5QYp1G5AtRvE2g1S7QZcu0Gu3UBqNyi1G9Seyan2TObaM5lrz2SuPZO59kzm2jOZa89kvsBMzmFqoGcWWOM4FXOWOU7xhaO+cMwVTg6+cI7nFbOMOCxyGueiPy+jnFx9l87X/mpfZMJRnuNkXzjiC6f4wlFfOOYKR4IvHPp/ODbfNMu1zx2e3sNL8oXDvnCyLxzxhePrdJSoLxxzhVOCLxzyheMrlYuvVC6+Urn4SuXiK5WLo1Te94e/Ftvl4m7Vvd9s+Pi6vv907+Hu93P3z22Iz9vNfffwuu2GGxI/7kUc8iuG1MbI/cscJgiptWQ2vOhwOAwtaR4O6VAb2hhiz9Bz/AE=","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"]}],"outputs":{"structs":{"functions":[{"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::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::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":[]}}]}]},"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(crate) 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"},"103":{"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\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.68.0/noir-projects/aztec-nr/aztec/src/state_vars/map.nr"},"116":{"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\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.68.0/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr"},"120":{"source":"use dep::protocol_types::debug_log::debug_log_format;\n\nuse crate::{\n context::{inputs::PrivateContextInputs, packed_returns::PackedReturns},\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 arguments,\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 key_validation_request::get_key_validation_request,\n returns::pack_returns,\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 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 self.nullifiers.push(\n Nullifier {\n value: nullifier,\n note_hash: nullified_note_hash,\n counter: self.next_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 pack_returns(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 let request = unsafe { get_key_validation_request(pk_m_hash, key_index) };\n assert(request.pk_m.hash() == pk_m_hash);\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 ) -> PackedReturns {\n let args_hash = hash_args_array(args);\n arguments::pack_arguments_array(args);\n self.call_private_function_with_packed_args(\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 ) -> PackedReturns {\n let args_hash = hash_args_array(args);\n arguments::pack_arguments_array(args);\n self.call_private_function_with_packed_args(\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 ) -> PackedReturns {\n self.call_private_function_with_packed_args(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 ) -> PackedReturns {\n self.call_private_function_with_packed_args(contract_address, function_selector, 0, true)\n }\n\n pub fn call_private_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field,\n is_static_call: bool,\n ) -> PackedReturns {\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 // The oracle simulates the private call and returns the value of the side effects counter after execution of\n // the call (which means that end_side_effect_counter - start_side_effect_counter is the number of side effects\n // that took place), along with the hash of the return values. We validate these by requesting a private kernel\n // iteration in which the return values are constrained to hash to `returns_hash` and the side effects counter\n // 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 PackedReturns::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 arguments::pack_arguments_array(args);\n self.call_public_function_with_packed_args(\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 arguments::pack_arguments_array(args);\n self.call_public_function_with_packed_args(\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_packed_args(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_packed_args(contract_address, function_selector, 0, true)\n }\n\n pub fn call_public_function_with_packed_args(\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 // TODO(https://github.com/AztecProtocol/aztec-packages/issues/8985): Fix this.\n // WARNING: This is insecure and should be temporary!\n // The oracle repacks 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 = enqueue_public_function_call_internal(\n contract_address,\n function_selector,\n args_hash,\n counter,\n is_static_call,\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 arguments::pack_arguments_array(args);\n self.set_public_teardown_function_with_packed_args(\n contract_address,\n function_selector,\n args_hash,\n false,\n )\n }\n\n pub fn set_public_teardown_function_with_packed_args(\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 // TODO(https://github.com/AztecProtocol/aztec-packages/issues/8985): Fix this.\n // WARNING: This is insecure and should be temporary!\n // The oracle repacks 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 = set_public_teardown_function_call_internal(\n contract_address,\n function_selector,\n args_hash,\n counter,\n is_static_call,\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.68.0/noir-projects/aztec-nr/aztec/src/context/private_context.nr"},"121":{"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::arguments::pack_arguments;\n\npub trait CallInterface {\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 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 pack_arguments(self.args);\n let returns = context.call_private_function_with_packed_args(\n self.target_contract,\n self.selector,\n self.args_hash,\n false,\n );\n let unpacked: T = returns.unpack_into();\n unpacked\n }\n\n pub fn view(self, context: &mut PrivateContext) -> T\n where\n T: Deserialize,\n {\n pack_arguments(self.args);\n let returns = context.call_private_function_with_packed_args(\n self.target_contract,\n self.selector,\n self.args_hash,\n true,\n );\n returns.unpack_into()\n }\n}\n\nimpl CallInterface for PrivateVoidCallInterface {}\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 pack_arguments(self.args);\n context\n .call_private_function_with_packed_args(\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 pack_arguments(self.args);\n context\n .call_private_function_with_packed_args(\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\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 pack_arguments(self.args);\n let returns = context.call_private_function_with_packed_args(\n self.target_contract,\n self.selector,\n self.args_hash,\n true,\n );\n returns.unpack_into()\n }\n}\n\nimpl CallInterface for PrivateStaticVoidCallInterface {}\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 pack_arguments(self.args);\n context\n .call_private_function_with_packed_args(\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\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 pack_arguments(self.args);\n context.call_public_function_with_packed_args(\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 pack_arguments(self.args);\n context.call_public_function_with_packed_args(\n self.target_contract,\n self.selector,\n args_hash,\n /*static=*/\n true,\n )\n }\n}\n\nimpl CallInterface for PublicVoidCallInterface {}\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 pack_arguments(self.args);\n context.call_public_function_with_packed_args(\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 pack_arguments(self.args);\n context.call_public_function_with_packed_args(\n self.target_contract,\n self.selector,\n args_hash,\n /*static=*/\n true,\n )\n }\n}\n\nimpl CallInterface for PublicStaticCallInterface {}\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 pack_arguments(self.args);\n context.call_public_function_with_packed_args(\n self.target_contract,\n self.selector,\n args_hash,\n /*static=*/\n true,\n )\n }\n}\n\nimpl CallInterface for PublicStaticVoidCallInterface {}\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 pack_arguments(self.args);\n context.call_public_function_with_packed_args(\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.68.0/noir-projects/aztec-nr/aztec/src/context/call_interfaces.nr"},"122":{"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.68.0/noir-projects/aztec-nr/aztec/src/context/unconstrained_context.nr"},"128":{"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 // 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 // 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 // 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 // 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 // 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 // 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 // AVM opcodes are constrained by the AVM itself\n unsafe { emit_nullifier(nullifier) };\n }\n\n pub fn this_address(_self: Self) -> AztecAddress {\n // AVM opcodes are constrained by the AVM itself\n unsafe {\n address()\n }\n }\n pub fn msg_sender(_self: Self) -> AztecAddress {\n // 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 // 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 // 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 // AVM opcodes are constrained by the AVM itself\n unsafe {\n chain_id()\n }\n }\n pub fn version(_self: Self) -> Field {\n // AVM opcodes are constrained by the AVM itself\n unsafe {\n version()\n }\n }\n pub fn block_number(_self: Self) -> Field {\n // AVM opcodes are constrained by the AVM itself\n unsafe {\n block_number()\n }\n }\n pub fn timestamp(_self: Self) -> u64 {\n // 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 // 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 // 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 // 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 // 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 // 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 // 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 // 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.68.0/noir-projects/aztec-nr/aztec/src/context/public_context.nr"},"130":{"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.68.0/noir-projects/aztec-nr/aztec/src/hash.nr"},"145":{"source":"/// Notifies the simulator that `args` will later be used at some point during execution, referenced by their hash. This\n/// allows the simulator to know how to respond to this future request.\n///\n/// This is only used during private execution, since in public it is the VM itself that keeps track of arguments.\npub fn pack_arguments(args: [Field]) {\n // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe to call. When\n // unpacking however the caller must check that the returned value is indeed the preimage.\n unsafe { pack_arguments_oracle_wrapper(args) };\n}\n\n/// Same as `pack_arguments`, but using arrays instead of slices.\npub fn pack_arguments_array(args: [Field; N]) {\n // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe to call. When\n // unpacking however the caller must check that the returned value is indeed the preimage.\n unsafe { pack_arguments_array_oracle_wrapper(args) };\n}\n\nunconstrained fn pack_arguments_oracle_wrapper(args: [Field]) {\n let _ = pack_arguments_oracle(args);\n}\n\nunconstrained fn pack_arguments_array_oracle_wrapper(args: [Field; N]) {\n let _ = pack_arguments_array_oracle(args);\n}\n\n#[oracle(packArguments)]\nunconstrained fn pack_arguments_oracle(_args: [Field]) -> Field {}\n\n#[oracle(packArgumentsArray)]\nunconstrained fn pack_arguments_array_oracle(_args: [Field; N]) -> Field {}\n","path":"/home/filip/nargo/github.com/AztecProtocol/aztec-packages/aztec-packages-v0.68.0/noir-projects/aztec-nr/aztec/src/oracle/arguments.nr"},"146":{"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 let instance =\n unsafe { ContractInstance::deserialize(get_contract_instance_internal(address)) };\n // The to_address function combines all values in the instance object to produce an address, so by checking that we\n // get the expected address we validate the entire struct.\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 let (member, exists) = 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 let (member, exists) = 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 let (member, exists) = 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.68.0/noir-projects/aztec-nr/aztec/src/oracle/get_contract_instance.nr"},"153":{"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.68.0/noir-projects/aztec-nr/aztec/src/oracle/execution.nr"},"154":{"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 // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe 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 // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe to call.\n unsafe { notify_nullified_note_oracle_wrapper(nullifier, note_hash, counter) };\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\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 // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe 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 // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe 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.68.0/noir-projects/aztec-nr/aztec/src/oracle/notes.nr"},"155":{"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 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.68.0/noir-projects/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr"},"156":{"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.68.0/noir-projects/aztec-nr/aztec/src/oracle/storage.nr"},"171":{"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\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.68.0/noir-projects/aztec-nr/aztec/src/initializer.nr"},"177":{"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, 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::embedded_curve_ops::{EmbeddedCurveScalar, fixed_base_scalar_mul as derive_public_key};\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.68.0/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr"},"189":{"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.68.0/noir-projects/noir-protocol-circuits/crates/types/src/type_serialization.nr"},"207":{"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.68.0/noir-projects/noir-protocol-circuits/crates/types/src/utils/reader.nr"},"211":{"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\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 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: validate_array(array) should be true.\npub fn array_length(array: [T; N]) -> u32\nwhere\n T: Empty + Eq,\n{\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]\nfn find_index_greater_than_min() {\n let values = [10, 20, 30, 40];\n let min = 22;\n let index = unsafe { find_index_hint(values, |v: Field| min.lt(v)) };\n assert_eq(index, 2);\n}\n\n#[test]\nfn find_index_not_found() {\n let values = [10, 20, 30, 40];\n let min = 100;\n let index = unsafe { 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 concated = array_concat(array0, array1);\n assert_eq(concated, [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.68.0/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr"},"221":{"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.68.0/noir-projects/noir-protocol-circuits/crates/types/src/traits.nr"},"223":{"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::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 traits::{is_empty, ToField},\n utils::field::field_from_bytes_32_trunc,\n};\nuse super::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\nfn compute_note_hash_nonce(tx_hash: Field, note_index_in_tx: u32) -> Field {\n // Hashing tx hash with note index in tx is guaranteed to be unique\n poseidon2_hash_with_separator(\n [tx_hash, 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 tx_hash: 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(tx_hash, 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: BoundedVec = BoundedVec::new();\n\n let inputs =\n [contract_address.to_field(), rollup_version_id, recipient.to_field(), chain_id, content];\n for i in 0..inputs.len() {\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.push(item_bytes[j]);\n }\n }\n\n sha256_to_field(bytes.storage())\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) -> std::hash::poseidon2::Poseidon2 {\n let two_pow_64 = 18446744073709551616;\n let iv: Field = (in_len as Field) * two_pow_64;\n let mut sponge = std::hash::poseidon2::Poseidon2::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: std::hash::poseidon2::Poseidon2,\n input: [Field; N],\n in_len: u32,\n skip_0_check: bool,\n) -> std::hash::poseidon2::Poseidon2 {\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: std::hash::poseidon2::Poseidon2,\n input: [Field; N],\n in_len: u32,\n variable: bool,\n shift: u32,\n) -> std::hash::poseidon2::Poseidon2 {\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 two_pow_64 = 18446744073709551616;\n let iv: Field = (in_len as Field) * two_pow_64;\n let mut sponge = std::hash::poseidon2::Poseidon2::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 two_pow_64 = 18446744073709551616;\n let empty_sponge = std::hash::poseidon2::Poseidon2::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 = std::hash::poseidon2::Poseidon2::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.68.0/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr"},"257":{"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.68.0/noir-projects/noir-protocol-circuits/crates/types/src/abis/function_selector.nr"},"312":{"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};\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.68.0/noir-projects/noir-protocol-circuits/crates/types/src/storage/map.nr"}}} \ No newline at end of file diff --git a/services/explorer-api/migrations/0000_tearful_black_queen.sql b/services/explorer-api/migrations/0000_bored_mandrill.sql similarity index 97% rename from services/explorer-api/migrations/0000_tearful_black_queen.sql rename to services/explorer-api/migrations/0000_bored_mandrill.sql index fe03b9fa..910515fc 100644 --- a/services/explorer-api/migrations/0000_tearful_black_queen.sql +++ b/services/explorer-api/migrations/0000_bored_mandrill.sql @@ -56,8 +56,7 @@ CREATE TABLE IF NOT EXISTS "public_data_write" ( ); --> statement-breakpoint CREATE TABLE IF NOT EXISTS "tx_effect" ( - "hash" varchar PRIMARY KEY NOT NULL, - "txHash" varchar NOT NULL, + "tx_hash" varchar PRIMARY KEY NOT NULL, "body_id" uuid NOT NULL, "tx_time_of_birth" timestamp DEFAULT now() NOT NULL, "index" integer NOT NULL, @@ -79,7 +78,7 @@ CREATE TABLE IF NOT EXISTS "content_commitment" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "header_id" uuid NOT NULL, "num_txs" bigint NOT NULL, - "txs_effects_hash" "bytea" NOT NULL, + "blobs_hash" "bytea" NOT NULL, "in_hash" "bytea" NOT NULL, "out_hash" "bytea" NOT NULL ); @@ -249,7 +248,7 @@ EXCEPTION END $$; --> statement-breakpoint DO $$ BEGIN - ALTER TABLE "public_data_write" ADD CONSTRAINT "public_data_write_tx_effect_hash_tx_effect_hash_fk" FOREIGN KEY ("tx_effect_hash") REFERENCES "public"."tx_effect"("hash") ON DELETE cascade ON UPDATE no action; + 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 WHEN duplicate_object THEN null; END $$; @@ -261,7 +260,7 @@ EXCEPTION END $$; --> statement-breakpoint DO $$ BEGIN - ALTER TABLE "tx_effect_to_logs" ADD CONSTRAINT "tx_effect_to_logs_tx_effect_hash_tx_effect_hash_fk" FOREIGN KEY ("tx_effect_hash") REFERENCES "public"."tx_effect"("hash") ON DELETE cascade ON UPDATE no action; + 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 $$; @@ -350,4 +349,4 @@ EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint -CREATE INDEX IF NOT EXISTS "tx_hash_index" ON "tx_effect" USING btree ("txHash"); \ No newline at end of file +CREATE INDEX IF NOT EXISTS "tx_hash_index" ON "tx_effect" USING btree ("tx_hash"); \ No newline at end of file diff --git a/services/explorer-api/migrations/meta/0000_snapshot.json b/services/explorer-api/migrations/meta/0000_snapshot.json index 4bb9a468..43f0ba0d 100644 --- a/services/explorer-api/migrations/meta/0000_snapshot.json +++ b/services/explorer-api/migrations/meta/0000_snapshot.json @@ -1,5 +1,5 @@ { - "id": "cd3636b0-cd9e-4f27-9e8f-05535d9f3d47", + "id": "d0b3729c-fa2b-4e34-bf10-58b2a86b5276", "prevId": "00000000-0000-0000-0000-000000000000", "version": "7", "dialect": "postgresql", @@ -335,12 +335,12 @@ }, "indexes": {}, "foreignKeys": { - "public_data_write_tx_effect_hash_tx_effect_hash_fk": { - "name": "public_data_write_tx_effect_hash_tx_effect_hash_fk", + "public_data_write_tx_effect_hash_tx_effect_tx_hash_fk": { + "name": "public_data_write_tx_effect_hash_tx_effect_tx_hash_fk", "tableFrom": "public_data_write", "tableTo": "tx_effect", "columnsFrom": ["tx_effect_hash"], - "columnsTo": ["hash"], + "columnsTo": ["tx_hash"], "onDelete": "cascade", "onUpdate": "no action" } @@ -352,18 +352,12 @@ "name": "tx_effect", "schema": "", "columns": { - "hash": { - "name": "hash", + "tx_hash": { + "name": "tx_hash", "type": "varchar", "primaryKey": true, "notNull": true }, - "txHash": { - "name": "txHash", - "type": "varchar", - "primaryKey": false, - "notNull": true - }, "body_id": { "name": "body_id", "type": "uuid", @@ -431,7 +425,7 @@ "name": "tx_hash_index", "columns": [ { - "expression": "txHash", + "expression": "tx_hash", "isExpression": false, "asc": true, "nulls": "last" @@ -477,12 +471,12 @@ }, "indexes": {}, "foreignKeys": { - "tx_effect_to_logs_tx_effect_hash_tx_effect_hash_fk": { - "name": "tx_effect_to_logs_tx_effect_hash_tx_effect_hash_fk", + "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": ["hash"], + "columnsTo": ["tx_hash"], "onDelete": "cascade", "onUpdate": "no action" } @@ -513,8 +507,8 @@ "primaryKey": false, "notNull": true }, - "txs_effects_hash": { - "name": "txs_effects_hash", + "blobs_hash": { + "name": "blobs_hash", "type": "bytea", "primaryKey": false, "notNull": true diff --git a/services/explorer-api/migrations/meta/_journal.json b/services/explorer-api/migrations/meta/_journal.json index cc0ef565..3ef80f69 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": 1734432721305, - "tag": "0000_tearful_black_queen", + "when": 1736164898806, + "tag": "0000_bored_mandrill", "breakpoints": true } ] diff --git a/services/explorer-api/src/database/controllers/l2/search.ts b/services/explorer-api/src/database/controllers/l2/search.ts index 4e744e77..13556164 100644 --- a/services/explorer-api/src/database/controllers/l2/search.ts +++ b/services/explorer-api/src/database/controllers/l2/search.ts @@ -46,13 +46,13 @@ const matchTxEffect = async ( ): Promise => { const res = await db() .select({ - hash: txEffect.hash, + hash: txEffect.txHash, }) .from(txEffect) - .where(or(eq(txEffect.hash, hash), eq(txEffect.txHash, hash))) + .where(or(eq(txEffect.txHash, hash), eq(txEffect.txHash, hash))) .execute(); if (res.length === 0) return []; - return [{ hash: res[0].hash }]; + return [{ txHash: res[0].hash }]; }; const matchContractClass = async ( diff --git a/services/explorer-api/src/database/controllers/l2TxEffect/get-tx-effect.ts b/services/explorer-api/src/database/controllers/l2TxEffect/get-tx-effect.ts index 6ed7d55b..3be3a044 100644 --- a/services/explorer-api/src/database/controllers/l2TxEffect/get-tx-effect.ts +++ b/services/explorer-api/src/database/controllers/l2TxEffect/get-tx-effect.ts @@ -46,7 +46,7 @@ export const getTxEffectNestedByHash = async ( ...getTableColumns(publicDataWrite), }) .from(publicDataWrite) - .innerJoin(txEffect, eq(txEffect.hash, publicDataWrite.txEffectHash)) + .innerJoin(txEffect, eq(txEffect.txHash, publicDataWrite.txEffectHash)) .where(eq(publicDataWrite.txEffectHash, txEffectHash)) .orderBy(asc(publicDataWrite.index)) .execute(); @@ -158,7 +158,7 @@ const _getTxEffects = async ( const txEffects = await Promise.all( dbRes.map(async (txEffect) => { - const nestedData = await getTxEffectNestedByHash(txEffect.hash); + const nestedData = await getTxEffectNestedByHash(txEffect.txHash); return { ...txEffect, txBirthTimestamp: txEffect.txBirthTimestamp.valueOf(), @@ -179,7 +179,7 @@ export const getTxEffectByTxHash = async ( export const getTxEffectByHash = async ( hash: HexString ): Promise => { - return getTxEffectDynamicWhere(eq(txEffect.hash, hash)); + return getTxEffectDynamicWhere(eq(txEffect.txHash, hash)); }; export const getTxEffectDynamicWhere = async ( @@ -202,7 +202,7 @@ export const getTxEffectDynamicWhere = async ( if (dbRes.length === 0) return null; - const nestedData = await getTxEffectNestedByHash(dbRes[0].hash); + const nestedData = await getTxEffectNestedByHash(dbRes[0].txHash); return chicmozL2TxEffectDeluxeSchema.parse({ ...dbRes[0], diff --git a/services/explorer-api/src/database/controllers/l2block/get-block.ts b/services/explorer-api/src/database/controllers/l2block/get-block.ts index ce3e1c75..fc189316 100644 --- a/services/explorer-api/src/database/controllers/l2block/get-block.ts +++ b/services/explorer-api/src/database/controllers/l2block/get-block.ts @@ -145,7 +145,7 @@ const _getBlocks = async (args: GetBlocksArgs): Promise = for (const result of results) { const txEffectsHashes = await db() .select({ - hash: txEffect.hash, + txHash: txEffect.txHash, }) .from(txEffect) .where(eq(txEffect.bodyId, result.bodyId)) diff --git a/services/explorer-api/src/database/controllers/l2block/store.ts b/services/explorer-api/src/database/controllers/l2block/store.ts index 34d3b84e..21b7ee7e 100644 --- a/services/explorer-api/src/database/controllers/l2block/store.ts +++ b/services/explorer-api/src/database/controllers/l2block/store.ts @@ -66,7 +66,7 @@ export const store = async (block: ChicmozL2Block): Promise => { id: contentCommitmentId, headerId: headerId, numTxs: block.header.contentCommitment.numTxs, - txsEffectsHash: block.header.contentCommitment.txsEffectsHash, + blobsHash: block.header.contentCommitment.blobsHash, inHash: block.header.contentCommitment.inHash, outHash: block.header.contentCommitment.outHash, }); @@ -157,7 +157,6 @@ export const store = async (block: ChicmozL2Block): Promise => { for (const [i, txEff] of Object.entries(block.body.txEffects)) { if (isNaN(Number(i))) throw new Error("Invalid txEffect index"); await dbTx.insert(txEffect).values({ - hash: txEff.hash, txHash: txEff.txHash, bodyId, index: Number(i), @@ -175,7 +174,7 @@ export const store = async (block: ChicmozL2Block): Promise => { const publicDataWriteId = uuidv4(); await dbTx.insert(publicDataWrite).values({ id: publicDataWriteId, - txEffectHash: txEff.hash, + txEffectHash: txEff.txHash, index: Number(pdwIndex), leafSlot: pdw.leafSlot, value: pdw.value, @@ -189,7 +188,7 @@ export const store = async (block: ChicmozL2Block): Promise => { // Create junction entry for txEffectToLogs await dbTx.insert(txEffectToLogs).values({ id: txEffectToLogsId, - txEffectHash: txEff.hash, + txEffectHash: txEff.txHash, }); for (const [functionLogIndex, functionLog] of Object.entries(fLogs)) { // Insert logs diff --git a/services/explorer-api/src/database/controllers/sign-of-life.ts b/services/explorer-api/src/database/controllers/sign-of-life.ts index a57552df..2265690d 100644 --- a/services/explorer-api/src/database/controllers/sign-of-life.ts +++ b/services/explorer-api/src/database/controllers/sign-of-life.ts @@ -36,16 +36,16 @@ export const getABlockWithTxEffects = async () => { hash: l2Block.hash, }, txEffects: - sql`COALESCE(json_agg(json_build_object('hash', ${txEffect.hash}, 'index', ${txEffect.index})) FILTER (WHERE ${txEffect.hash} IS NOT NULL), '[]'::json)`.as( + sql`COALESCE(json_agg(json_build_object('hash', ${txEffect.txHash}, 'index', ${txEffect.index})) FILTER (WHERE ${txEffect.txHash} IS NOT NULL), '[]'::json)`.as( "txEffects" ), - txEffectCount: sql`count(${txEffect.hash})`.as("txEffectCount"), + txEffectCount: sql`count(${txEffect.txHash})`.as("txEffectCount"), }) .from(txEffect) .innerJoin(body, eq(txEffect.bodyId, body.id)) .innerJoin(l2Block, eq(body.blockHash, l2Block.hash)) .groupBy(l2Block.height, l2Block.hash) - .orderBy(sql`count(${txEffect.hash}) DESC, ${l2Block.height} DESC`) + .orderBy(sql`count(${txEffect.txHash}) DESC, ${l2Block.height} DESC`) .limit(1) .execute(); @@ -69,14 +69,14 @@ export const getABlockWithTxEffects = async () => { export const getSomeTxEffectWithPrivateLogs = async () => { const dbRes = await db() .select({ - hash: txEffect.hash, + txHash: txEffect.txHash, }) .from(txEffect) .where(isNotNull(txEffect.privateLogs)) .limit(10) .execute(); if (dbRes.length === 0) return null; - return dbRes.map((row) => row.hash); + return dbRes.map((row) => row.txHash); }; export const getSomeTxEffectWithUnencryptedLogs = async () => { diff --git a/services/explorer-api/src/database/schema/l2block/body.ts b/services/explorer-api/src/database/schema/l2block/body.ts index bdad3d3c..cf3cb2da 100644 --- a/services/explorer-api/src/database/schema/l2block/body.ts +++ b/services/explorer-api/src/database/schema/l2block/body.ts @@ -28,8 +28,7 @@ export const body = pgTable("body", { export const txEffect = pgTable( "tx_effect", { - hash: varchar("hash").notNull().$type().primaryKey(), - txHash: varchar("txHash").notNull().$type(), + txHash: varchar("tx_hash").notNull().$type().primaryKey(), bodyId: uuid("body_id") .notNull() .references(() => body.id, { onDelete: "cascade" }), @@ -55,7 +54,7 @@ export const publicDataWrite = pgTable("public_data_write", { id: uuid("id").primaryKey().defaultRandom(), txEffectHash: varchar("tx_effect_hash") .notNull() - .references(() => txEffect.hash, { onDelete: "cascade" }), + .references(() => txEffect.txHash, { onDelete: "cascade" }), index: integer("index").notNull(), leafSlot: generateFrColumn("leaf_slot").notNull(), value: generateFrColumn("value").notNull(), @@ -85,5 +84,5 @@ export const txEffectToLogs = pgTable("tx_effect_to_logs", { id: uuid("id").primaryKey().defaultRandom(), txEffectHash: varchar("tx_effect_hash") .notNull() - .references(() => txEffect.hash, { onDelete: "cascade" }), + .references(() => txEffect.txHash, { onDelete: "cascade" }), }); diff --git a/services/explorer-api/src/database/schema/l2block/header.ts b/services/explorer-api/src/database/schema/l2block/header.ts index 8e6aee0e..de983b03 100644 --- a/services/explorer-api/src/database/schema/l2block/header.ts +++ b/services/explorer-api/src/database/schema/l2block/header.ts @@ -31,7 +31,7 @@ export const contentCommitment = pgTable("content_commitment", { .notNull() .references(() => header.id, { onDelete: "cascade" }), numTxs: generateFrNumberColumn("num_txs").notNull(), - txsEffectsHash: bufferType("txs_effects_hash").notNull(), + blobsHash: bufferType("blobs_hash").notNull(), inHash: bufferType("in_hash").notNull(), outHash: bufferType("out_hash").notNull(), }); diff --git a/services/explorer-api/src/database/schema/l2block/relations.ts b/services/explorer-api/src/database/schema/l2block/relations.ts index 000b9a9e..5e759038 100644 --- a/services/explorer-api/src/database/schema/l2block/relations.ts +++ b/services/explorer-api/src/database/schema/l2block/relations.ts @@ -165,7 +165,7 @@ export const functionLogsRelations = relations(functionLogs, ({ many }) => ({ export const txEffectToLogsRelations = relations(txEffectToLogs, ({ one }) => ({ txEffect: one(txEffect, { fields: [txEffectToLogs.txEffectHash], - references: [txEffect.hash], + references: [txEffect.txHash], }), log: one(logs, { fields: [txEffectToLogs.id], diff --git a/services/explorer-ui/src/components/header.tsx b/services/explorer-ui/src/components/header.tsx index 7a45f92e..42b1182d 100644 --- a/services/explorer-ui/src/components/header.tsx +++ b/services/explorer-ui/src/components/header.tsx @@ -33,7 +33,7 @@ export const Header = () => { void navigate({ to: `/blocks/${block.hash}` }); setIsMenuOpen(false); } else if (txEffect) { - void navigate({ to: `/tx-effects/${txEffect.hash}` }); + void navigate({ to: `/tx-effects/${txEffect.txHash}` }); setIsMenuOpen(false); } else if (instance) { void navigate({ to: `/contracts/instances/${instance.address}` }); diff --git a/services/explorer-ui/src/components/tx-effects/tx-effects-columns.tsx b/services/explorer-ui/src/components/tx-effects/tx-effects-columns.tsx index fb6f8b93..5a425a27 100644 --- a/services/explorer-ui/src/components/tx-effects/tx-effects-columns.tsx +++ b/services/explorer-ui/src/components/tx-effects/tx-effects-columns.tsx @@ -4,12 +4,10 @@ import { routes } from "~/routes/__root"; import { DataTableColumnHeader } from "~/components/data-table"; import { type TxEffectTableSchema } from "./tx-effects-schema"; import { formatTimeSince } from "~/lib/utils"; -import { CopyableText } from "../copy-text"; import { truncateHashString } from "~/lib/create-hash-string"; const text = { - hash: "TX EFFECT HASH", - txHash: "TX HASH", + txHash: "HASH", transactionFee: "FEE (FPA)", blockHeight: "HEIGHT", timeSince: "AGE", @@ -17,19 +15,19 @@ const text = { export const TxEffectsTableColumns: ColumnDef[] = [ { - accessorKey: "hash", + accessorKey: "txHash", header: ({ column }) => ( ), cell: ({ row }) => { - const hash = row.getValue("hash"); + const hash = row.getValue("txHash"); if (typeof hash !== "string") return null; const r = `${routes.txEffects.route}/${hash}`; - const truncatedTxHash = `${hash.slice(0, 6)}...${hash.slice(-4)}`; + const truncatedTxHash = truncateHashString(hash); return (
{truncatedTxHash} @@ -37,24 +35,6 @@ export const TxEffectsTableColumns: ColumnDef[] = [ ); }, }, - { - accessorKey: "txHash", - header: ({ column }) => ( - - ), - cell: ({ row }) => ( - - ), - enableSorting: false, - enableHiding: false, - }, { accessorKey: "timestamp", header: ({ column }) => ( diff --git a/services/explorer-ui/src/components/tx-effects/tx-effects-schema.ts b/services/explorer-ui/src/components/tx-effects/tx-effects-schema.ts index 3803469a..fc826de6 100644 --- a/services/explorer-ui/src/components/tx-effects/tx-effects-schema.ts +++ b/services/explorer-ui/src/components/tx-effects/tx-effects-schema.ts @@ -11,7 +11,6 @@ export const getTxEffectTableObj = ( block: ChicmozL2BlockLight ): TxEffectTableSchema => { return txEffectSchema.parse({ - hash: txEffect.hash, txHash: txEffect.txHash, transactionFee: txEffect.transactionFee, blockNumber: block.height, @@ -20,7 +19,6 @@ export const getTxEffectTableObj = ( }; const txEffectSchema = z.object({ - hash: z.string(), txHash: z.string(), transactionFee: z.number(), blockNumber: z.number(), diff --git a/services/explorer-ui/src/hooks/websocket.ts b/services/explorer-ui/src/hooks/websocket.ts index 710cd6d6..9e8e4163 100644 --- a/services/explorer-ui/src/hooks/websocket.ts +++ b/services/explorer-ui/src/hooks/websocket.ts @@ -5,7 +5,7 @@ import { type ChicmozL2Block, type ChicmozL2BlockLight, type ChicmozL2PendingTx, - type WebsocketUpdateMessage, + type WebsocketUpdateMessageReceiver, } from "@chicmoz-pkg/types"; import { useQueryClient } from "@tanstack/react-query"; import { useEffect } from "react"; @@ -35,7 +35,7 @@ const updateTxEffects = ( const txEffects = block.body.txEffects.map((txEffect) => { const effect = chicmozL2TxEffectSchema.parse(txEffect); queryClient.setQueryData( - queryKeyGenerator.txEffectByHash(effect.hash), + queryKeyGenerator.txEffectByHash(effect.txHash), { ...effect, blockHeight: block.height, @@ -105,9 +105,9 @@ const handleWebSocketMessage = async ( queryClient: ReturnType, data: string ) => { - const update: WebsocketUpdateMessage = JSON.parse( + const update: WebsocketUpdateMessageReceiver = JSON.parse( data - ) as WebsocketUpdateMessage; + ) as WebsocketUpdateMessageReceiver; if (update.block) await handleBlock(queryClient, update.block); if (update.txs) handlePendingTxs(queryClient, update.txs); }; diff --git a/services/explorer-ui/src/pages/landing/index.tsx b/services/explorer-ui/src/pages/landing/index.tsx index 6201b923..ce645dc0 100644 --- a/services/explorer-ui/src/pages/landing/index.tsx +++ b/services/explorer-ui/src/pages/landing/index.tsx @@ -14,7 +14,7 @@ import { mapLatestBlocks, parseTxEffectsData } from "./util"; import { InfoBadge } from "~/components/info-badge"; import { formatDuration, formatFees } from "~/lib/utils"; import { usePendingTxs } from "~/hooks/tx"; -import { TxEffectTableSchema } from "~/components/tx-effects/tx-effects-schema"; +import { type TxEffectTableSchema } from "~/components/tx-effects/tx-effects-schema"; export const Landing: FC = () => { const { data: latestBlocks, isLoading, error } = useLatestBlocks(); @@ -66,7 +66,6 @@ export const Landing: FC = () => { const disguisedPendingTxs = pendingTxs?.reduce((acc, tx) => { if (!latestTxEffects.some((effect) => effect.txHash === tx.hash)) { acc.push({ - hash: "0x00000000", txHash: tx.hash, transactionFee: -1, blockNumber: -1, 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 46dbf2fa..e51c0b09 100644 --- a/services/explorer-ui/src/pages/tx-effect-details/utils.ts +++ b/services/explorer-ui/src/pages/tx-effect-details/utils.ts @@ -18,10 +18,6 @@ export type TxEffectDataType = export const getTxEffectData = (data: ChicmozL2TxEffectDeluxe) => [ { label: "HASH", - value: data.hash, - }, - { - label: "TRANSACTION HASH", value: data.txHash, }, { @@ -41,7 +37,7 @@ export const getTxEffectData = (data: ChicmozL2TxEffectDeluxe) => [ { label: "RAW DATA", value: "View raw data", - extLink: `${API_URL}/${aztecExplorer.getL2TxEffectByHash}${data.hash}`, + extLink: `${API_URL}/${aztecExplorer.getL2TxEffectByHash}${data.txHash}`, }, ]; diff --git a/services/websocket-event-publisher/src/ws-server/index.ts b/services/websocket-event-publisher/src/ws-server/index.ts index efe9e8f5..5bd265d8 100644 --- a/services/websocket-event-publisher/src/ws-server/index.ts +++ b/services/websocket-event-publisher/src/ws-server/index.ts @@ -1,7 +1,7 @@ import { ChicmozL2Block, ChicmozL2PendingTx, - WebsocketUpdateMessage, + WebsocketUpdateMessageSender, } from "@chicmoz-pkg/types"; import { WebSocketServer, WebSocket } from "ws"; import { logger } from "../logger.js"; @@ -9,7 +9,7 @@ import { PORT } from "../environment.js"; let wss: WebSocketServer; -const sendUpdateToClients = (update: WebsocketUpdateMessage) => { +const sendUpdateToClients = (update: WebsocketUpdateMessageSender) => { const stringifiedUpdate = JSON.stringify(update); if (!wss) throw new Error("WebSocket server is not initialized"); const clientStatuses: { @@ -43,7 +43,7 @@ const sendUpdateToClients = (update: WebsocketUpdateMessage) => { }; export const sendPendingTxsToClients = (txs: ChicmozL2PendingTx[]) => { - const update: WebsocketUpdateMessage = { txs }; + const update: WebsocketUpdateMessageSender = { txs }; const { clientStatuses, totalClients } = sendUpdateToClients(update); logger.info( `📡 Sent ${txs.length} pending txs to ${clientStatuses.sent} clients (failed: ${clientStatuses.failed}, total: ${totalClients})` @@ -51,8 +51,15 @@ export const sendPendingTxsToClients = (txs: ChicmozL2PendingTx[]) => { }; export const sendBlockToClients = (block: ChicmozL2Block) => { - const update: WebsocketUpdateMessage = { block }; - const { clientStatuses, totalClients } = sendUpdateToClients(update); + const { clientStatuses, totalClients } = sendUpdateToClients({ + block: { + ...block, + header: { + ...block.header, + totalFees: block.header.totalFees.toString(), + }, + }, + }); logger.info( `📡 Sent block ${block.header.globalVariables.blockNumber} to ${clientStatuses.sent} clients (failed: ${clientStatuses.failed}, total: ${totalClients})` ); From 2c215f4adfa381c6c45b79e8d701b64836b04ed8 Mon Sep 17 00:00:00 2001 From: filip Date: Tue, 7 Jan 2025 11:09:12 +0100 Subject: [PATCH 02/11] endpoint done --- k8s/local/skaffold.eth_and_az_nodes.yaml | 17 ++++ services/event-cannon/src/cannon/index.ts | 12 +-- services/event-cannon/src/cannon/pxe.ts | 15 ++++ .../routes/controllers/contract-classes.ts | 84 ++++++++++++++++++- .../routes/controllers/utils/db-wrapper.ts | 11 +-- .../routes/controllers/verified-contracts.ts | 2 +- .../routes/paths_and_validation.ts | 19 ++++- services/explorer-ui/src/api/search.ts | 6 +- 8 files changed, 146 insertions(+), 20 deletions(-) create mode 100644 k8s/local/skaffold.eth_and_az_nodes.yaml diff --git a/k8s/local/skaffold.eth_and_az_nodes.yaml b/k8s/local/skaffold.eth_and_az_nodes.yaml new file mode 100644 index 00000000..c674131f --- /dev/null +++ b/k8s/local/skaffold.eth_and_az_nodes.yaml @@ -0,0 +1,17 @@ +apiVersion: skaffold/v4beta6 +kind: Config +metadata: + name: chicmoz +deploy: + kubectl: + flags: + apply: ["--force"] +manifests: + rawYaml: + - k8s/local/common/namespace.yaml + - k8s/local/aztec-sandbox-node/ingress.yaml + - k8s/local/aztec-sandbox-node/deployment.yaml + - k8s/local/aztec-sandbox-node/service.yaml + - k8s/local/anvil-ethereum-node/ingress.yaml + - k8s/local/anvil-ethereum-node/deployment.yaml + - k8s/local/anvil-ethereum-node/service.yaml diff --git a/services/event-cannon/src/cannon/index.ts b/services/event-cannon/src/cannon/index.ts index a273553a..8ca523bf 100644 --- a/services/event-cannon/src/cannon/index.ts +++ b/services/event-cannon/src/cannon/index.ts @@ -17,13 +17,13 @@ export async function init() { export const start = async () => { logger.info("Starting Cannon..."); const scenariosToRun = [ - scenarios.deploySimpleDefaultAccount, - scenarios.deployAndInteractTokenContract, - scenarios.deployAndInteractFunctionsVote, - scenarios.deploySimpleContract, + //scenarios.deploySimpleDefaultAccount, + //scenarios.deployAndInteractTokenContract, + //scenarios.deployAndInteractFunctionsVote, + //scenarios.deploySimpleContract, scenarios.deploySimpleLog, - scenarios.l1L2PublicMessaging, - scenarios.l1L2PrivateMessaging, + //scenarios.l1L2PublicMessaging, + //scenarios.l1L2PrivateMessaging, ] as (() => Promise)[]; for (const fn of scenariosToRun) await fn(); }; diff --git a/services/event-cannon/src/cannon/pxe.ts b/services/event-cannon/src/cannon/pxe.ts index 6a0010c1..4cda78e0 100644 --- a/services/event-cannon/src/cannon/pxe.ts +++ b/services/event-cannon/src/cannon/pxe.ts @@ -18,8 +18,18 @@ let namedWallets: { charlie: AccountWallet; } | null = null; +let version: string | null = null; + export const setup = async () => { aztecNode = createAztecNodeClient(AZTEC_RPC_URL); + const v = await aztecNode.getNodeVersion(); + if (v === "0.1.0") { + // TODO: this is a temporary workaround for the versioning issue + version = "0.69.0"; + } else { + logger.info(`Finally the getNodeVersion is working! ${v}`); + version = v; + } pxe = createPXEClient(AZTEC_RPC_URL); await waitForPXE(pxe); const info = await pxe.getPXEInfo(); @@ -32,6 +42,11 @@ export const setup = async () => { }; }; +export const getNodeVersion = () => { + if (!version) throw new Error("Version not initialized"); + return version; +} + export const getAztecNodeClient = () => { if (!aztecNode) throw new Error("Aztec Node not initialized"); return aztecNode; diff --git a/services/explorer-api/src/http-server/routes/controllers/contract-classes.ts b/services/explorer-api/src/http-server/routes/controllers/contract-classes.ts index 5870605b..46c95f16 100644 --- a/services/explorer-api/src/http-server/routes/controllers/contract-classes.ts +++ b/services/explorer-api/src/http-server/routes/controllers/contract-classes.ts @@ -1,14 +1,22 @@ +import { + getContractClassFromArtifact, + loadContractArtifact, + type NoirCompiledContract, +} from "@aztec/aztec.js"; import asyncHandler from "express-async-handler"; import { controllers as db } from "../../../database/index.js"; import { - getContractClassSchema, getContractClassesByClassIdSchema, + getContractClassSchema, + postContrctClassArtifactSchema, } from "../paths_and_validation.js"; import { contractClassResponse, contractClassResponseArray, dbWrapper, } from "./utils/index.js"; +import { chicmozL2ContractClassRegisteredEventSchema } from "@chicmoz-pkg/types"; +import { logger } from "../../../logger.js"; export const openapi_GET_L2_REGISTERED_CONTRACT_CLASS = { "/l2/contract-classes/{classId}/versions/{version}": { @@ -41,7 +49,7 @@ export const GET_L2_REGISTERED_CONTRACT_CLASS = asyncHandler( async (req, res) => { const { classId, version } = getContractClassSchema.parse(req).params; const contractClass = await dbWrapper.get( - ["l2", "contract-classes", classId], + ["l2", "contract-classes", classId, version], () => db.l2Contract.getL2RegisteredContractClass(classId, version) ); res.status(200).send(contractClass); @@ -97,3 +105,75 @@ export const GET_L2_REGISTERED_CONTRACT_CLASSES = asyncHandler( res.status(200).send(contractClasses); } ); + +export const openapi_POST_L2_REGISTERED_CONTRACT_CLASS_ARTIFACT = { + "/l2/contract-classes/{classId}/versions/{version}/artifact": { + post: { + summary: "Register and verify contract class artifact", + parameters: [ + { + name: "classId", + in: "path", + required: true, + schema: { + type: "string", + }, + }, + { + name: "version", + in: "path", + required: true, + schema: { + type: "string", + }, + }, + ], + requestBody: { + content: { + "application/json": { + schema: { + type: "object", + properties: { + stringifiedArtifactJson: { + type: "string", + }, + }, + }, + }, + }, + }, + // TODO: add response schema + responses: contractClassResponse, + }, + }, +}; + +export const POST_L2_REGISTERED_CONTRACT_CLASS_ARTIFACT = asyncHandler( + async (req, res) => { + const { + params: { classId, version }, + body: { stringifiedArtifactJson }, + } = postContrctClassArtifactSchema.parse(req); + const contractClassString = await dbWrapper.get( + ["l2", "contract-classes", classId, version], + () => db.l2Contract.getL2RegisteredContractClass(classId, version) + ); + //ChicmozL2ContractClassRegisteredEvent + const contractClass = + chicmozL2ContractClassRegisteredEventSchema.parse(contractClassString); + const uploadedArtifact = getContractClassFromArtifact( + loadContractArtifact( + stringifiedArtifactJson as unknown as NoirCompiledContract + ) + ); + const isCorrectArtifact = + uploadedArtifact.packedBytecode === contractClass.packedBytecode; + logger.info(`🔍🔍🔍🔍🔍🔍🔍🔍🔍🔍🔍🔍 + ${uploadedArtifact.packedBytecode.toString()} + ${contractClass.packedBytecode.toString()} + ${isCorrectArtifact} + `); + if (!isCorrectArtifact) throw new Error("Incorrect artifact"); + res.status(200).send(isCorrectArtifact); + } +); diff --git a/services/explorer-api/src/http-server/routes/controllers/utils/db-wrapper.ts b/services/explorer-api/src/http-server/routes/controllers/utils/db-wrapper.ts index 4419b2f9..308072f0 100644 --- a/services/explorer-api/src/http-server/routes/controllers/utils/db-wrapper.ts +++ b/services/explorer-api/src/http-server/routes/controllers/utils/db-wrapper.ts @@ -35,7 +35,8 @@ export const getLatest = async( return get([...keys, latestHeight], dbFn, CACHE_LATEST_TTL_SECONDS + 1); }; -const json = (param: unknown): string => { +const jsonStringify = (param: unknown): string => { + // TODO: move this to backend-utils and make use of it in websockets as well return JSON.stringify( param, // eslint-disable-next-line @typescript-eslint/no-unsafe-return @@ -46,7 +47,7 @@ const json = (param: unknown): string => { export const get = async( keys: (string | number | undefined)[], dbFn: () => Promise, - ttl = CACHE_TTL_SECONDS + ttl = CACHE_TTL_SECONDS, ): Promise => { const cacheKey = keys.join("-"); const cachedVal = await c().get(cacheKey); @@ -58,11 +59,11 @@ export const get = async( const dbRes = await dbFn().catch(dbParseErrorCallback); if (dbRes !== null && dbRes !== undefined) { - const dbVal = json(dbRes); - await c().set(cacheKey, dbVal, { + const dbResString = jsonStringify(dbRes); + await c().set(cacheKey, dbResString, { EX: ttl, }); - return dbVal; + return dbResString; } throw new Error(`${cacheKey} not found`); }; diff --git a/services/explorer-api/src/http-server/routes/controllers/verified-contracts.ts b/services/explorer-api/src/http-server/routes/controllers/verified-contracts.ts index 9d000561..02a9d279 100644 --- a/services/explorer-api/src/http-server/routes/controllers/verified-contracts.ts +++ b/services/explorer-api/src/http-server/routes/controllers/verified-contracts.ts @@ -1,10 +1,10 @@ import { RequestHandler } from "express"; import { VERIFIED_CONTRACT_ADDRESSES } from "../../../environment.js"; +import { getVerifiedContractSchema } from "../paths_and_validation.js"; import { verifiedContractResponse, verifiedContractResponseArray, } from "./utils/open-api-responses.js"; -import { getVerifiedContractSchema } from "../paths_and_validation.js"; export const openapi_GET_L2_VERIFIED_CONTRACTS = { "/l2/verified-contracts": { diff --git a/services/explorer-api/src/http-server/routes/paths_and_validation.ts b/services/explorer-api/src/http-server/routes/paths_and_validation.ts index 7283a066..11ef4c44 100644 --- a/services/explorer-api/src/http-server/routes/paths_and_validation.ts +++ b/services/explorer-api/src/http-server/routes/paths_and_validation.ts @@ -116,16 +116,27 @@ export const getContractClassesByClassIdSchema = z.object({ }), }); -export const getContractClassPrivateFunctionsSchema = getContractClassesByClassIdSchema; +export const getContractClassPrivateFunctionsSchema = + getContractClassesByClassIdSchema; export const getContractClassPrivateFunctionSchema = z.object({ params: z.object({ [classId]: hexStringSchema, [functionSelector]: z.coerce.number().nonnegative(), }), }); -export const getContractClassUnconstrainedFunctionsSchema = getContractClassPrivateFunctionsSchema; -export const getContractClassUnconstrainedFunctionSchema = getContractClassPrivateFunctionSchema; - +export const getContractClassUnconstrainedFunctionsSchema = + getContractClassPrivateFunctionsSchema; +export const getContractClassUnconstrainedFunctionSchema = + getContractClassPrivateFunctionSchema; + +export const postContrctClassArtifactSchema = z.lazy(() => { + return z.object({ + ...getContractClassSchema.shape, + body: z.object({ + stringifiedArtifactJson: z.string(), + }), + }); +}); export const getContractInstancesByContractClassIdSchema = getContractClassesByClassIdSchema; diff --git a/services/explorer-ui/src/api/search.ts b/services/explorer-ui/src/api/search.ts index ab749f2f..39bd1d60 100644 --- a/services/explorer-ui/src/api/search.ts +++ b/services/explorer-ui/src/api/search.ts @@ -3,12 +3,14 @@ import client, { validateResponse } from "./client"; import { type ChicmozSearchResults, chicmozSearchResultsSchema, + chicmozSearchQuerySchema, } from "@chicmoz-pkg/types"; export const searchL2Api = { - search: async (query: string): Promise => { + search: async (queryString: string): Promise => { + const query = chicmozSearchQuerySchema.parse({ q: queryString }); const response = await client.get(aztecExplorer.getL2SearchResult, { - params: { q: query }, + params: query, }); return validateResponse(chicmozSearchResultsSchema, response.data); }, From 26968ddde4680b5c94e7d4f4da2c456979ca0715 Mon Sep 17 00:00:00 2001 From: filip Date: Tue, 7 Jan 2025 11:25:37 +0100 Subject: [PATCH 03/11] prep for next step --- packages/types/src/aztec/l2Contract.ts | 1 + .../src/cannon/scenarios/simple-deploy-contract.ts | 3 +++ .../{0000_bored_mandrill.sql => 0000_colorful_sway.sql} | 1 + services/explorer-api/migrations/meta/0000_snapshot.json | 8 +++++++- services/explorer-api/migrations/meta/_journal.json | 4 ++-- .../explorer-api/src/database/schema/l2contract/index.ts | 1 + 6 files changed, 15 insertions(+), 3 deletions(-) rename services/explorer-api/migrations/{0000_bored_mandrill.sql => 0000_colorful_sway.sql} (99%) diff --git a/packages/types/src/aztec/l2Contract.ts b/packages/types/src/aztec/l2Contract.ts index 9ff0d78e..c2da9f78 100644 --- a/packages/types/src/aztec/l2Contract.ts +++ b/packages/types/src/aztec/l2Contract.ts @@ -30,6 +30,7 @@ export const chicmozL2ContractClassRegisteredEventSchema = z.object({ artifactHash: frSchema, privateFunctionsRoot: frSchema, packedBytecode: bufferSchema, + artifactJson: z.any().optional(), }); export type ChicmozL2ContractClassRegisteredEvent = z.infer< diff --git a/services/event-cannon/src/cannon/scenarios/simple-deploy-contract.ts b/services/event-cannon/src/cannon/scenarios/simple-deploy-contract.ts index ea183ca8..42f3b163 100644 --- a/services/event-cannon/src/cannon/scenarios/simple-deploy-contract.ts +++ b/services/event-cannon/src/cannon/scenarios/simple-deploy-contract.ts @@ -23,4 +23,7 @@ export async function run() { deployFn: (): DeploySentTx => sentTx, node: getAztecNodeClient(), }); + + // TODO: 1. try to get the contract in explorer-api + // TODO: 2. try to verify the contract class code in explorer-api } diff --git a/services/explorer-api/migrations/0000_bored_mandrill.sql b/services/explorer-api/migrations/0000_colorful_sway.sql similarity index 99% rename from services/explorer-api/migrations/0000_bored_mandrill.sql rename to services/explorer-api/migrations/0000_colorful_sway.sql index 910515fc..0d0caa50 100644 --- a/services/explorer-api/migrations/0000_bored_mandrill.sql +++ b/services/explorer-api/migrations/0000_colorful_sway.sql @@ -165,6 +165,7 @@ CREATE TABLE IF NOT EXISTS "l2_contract_class_registered" ( "artifact_hash" varchar(66) NOT NULL, "private_functions_root" varchar(66) NOT NULL, "packed_bytecode" "bytea" NOT NULL, + "artifact_json" jsonb, CONSTRAINT "contract_class_id_version" PRIMARY KEY("contract_class_id","version") ); --> statement-breakpoint diff --git a/services/explorer-api/migrations/meta/0000_snapshot.json b/services/explorer-api/migrations/meta/0000_snapshot.json index 43f0ba0d..5512bc96 100644 --- a/services/explorer-api/migrations/meta/0000_snapshot.json +++ b/services/explorer-api/migrations/meta/0000_snapshot.json @@ -1,5 +1,5 @@ { - "id": "d0b3729c-fa2b-4e34-bf10-58b2a86b5276", + "id": "9c1c478b-6ab4-468c-9d51-8aa9e0f5631b", "prevId": "00000000-0000-0000-0000-000000000000", "version": "7", "dialect": "postgresql", @@ -1053,6 +1053,12 @@ "type": "bytea", "primaryKey": false, "notNull": true + }, + "artifact_json": { + "name": "artifact_json", + "type": "jsonb", + "primaryKey": false, + "notNull": false } }, "indexes": {}, diff --git a/services/explorer-api/migrations/meta/_journal.json b/services/explorer-api/migrations/meta/_journal.json index 3ef80f69..a2c05852 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": 1736164898806, - "tag": "0000_bored_mandrill", + "when": 1736245534764, + "tag": "0000_colorful_sway", "breakpoints": true } ] diff --git a/services/explorer-api/src/database/schema/l2contract/index.ts b/services/explorer-api/src/database/schema/l2contract/index.ts index 68b3c3fa..04bd1996 100644 --- a/services/explorer-api/src/database/schema/l2contract/index.ts +++ b/services/explorer-api/src/database/schema/l2contract/index.ts @@ -108,6 +108,7 @@ export const l2ContractClassRegistered = pgTable( artifactHash: generateFrColumn("artifact_hash").notNull(), privateFunctionsRoot: generateFrColumn("private_functions_root").notNull(), packedBytecode: bufferType("packed_bytecode").notNull(), + artifactJson: jsonb("artifact_json"), }, (t) => ({ primaryKey: primaryKey({ From 7203791a55d9223d9064e1ca4abbb358c7765920 Mon Sep 17 00:00:00 2001 From: filip Date: Wed, 8 Jan 2025 09:11:20 +0100 Subject: [PATCH 04/11] works in API --- k8s/local/event-cannon/deployment.yaml | 2 + packages/error-middleware/src/middleware.ts | 5 ++ packages/types/src/aztec/l2Contract.ts | 2 +- .../scenarios/deploy-and-run-simple-log.ts | 21 +++++- .../scenarios/simple-deploy-contract.ts | 4 +- .../src/cannon/scenarios/utils/index.ts | 67 +++++++++++++++++++ services/event-cannon/src/environment.ts | 2 + ...l_sway.sql => 0000_mute_kinsey_walden.sql} | 2 +- .../migrations/meta/0000_snapshot.json | 4 +- .../migrations/meta/_journal.json | 4 +- .../get-registered-contract-class.ts | 11 +-- .../database/controllers/l2contract/store.ts | 20 ++++++ .../src/database/schema/l2contract/index.ts | 2 +- services/explorer-api/src/environment.ts | 2 +- .../routes/controllers/contract-classes.ts | 30 ++++----- .../src/http-server/routes/index.ts | 2 + .../pages/contract-class-details/index.tsx | 3 + 17 files changed, 145 insertions(+), 38 deletions(-) rename services/explorer-api/migrations/{0000_colorful_sway.sql => 0000_mute_kinsey_walden.sql} (99%) diff --git a/k8s/local/event-cannon/deployment.yaml b/k8s/local/event-cannon/deployment.yaml index ba512a4f..699b4b7b 100644 --- a/k8s/local/event-cannon/deployment.yaml +++ b/k8s/local/event-cannon/deployment.yaml @@ -30,4 +30,6 @@ spec: value: "http://aztec-sandbox-node:8081" - name: ETHEREUM_RPC_URL value: "http://anvil-ethereum-node:8545" + - name: EXPLORER_API_URL + value: "http://explorer-api:80" status: {} diff --git a/packages/error-middleware/src/middleware.ts b/packages/error-middleware/src/middleware.ts index a24d88ba..9f15a8f2 100644 --- a/packages/error-middleware/src/middleware.ts +++ b/packages/error-middleware/src/middleware.ts @@ -16,6 +16,11 @@ export const createErrorMiddleware = (logger: Logger): ErrorRequestHandler => { else logger.error(err); } + if ((err as Error).message === "PayloadTooLargeError") { + res.status(413).send({ message: "Payload too large" }); + return; + } + if ( err instanceof UnauthorizedError || err instanceof InsufficientScopeError diff --git a/packages/types/src/aztec/l2Contract.ts b/packages/types/src/aztec/l2Contract.ts index c2da9f78..0c049d04 100644 --- a/packages/types/src/aztec/l2Contract.ts +++ b/packages/types/src/aztec/l2Contract.ts @@ -30,7 +30,7 @@ export const chicmozL2ContractClassRegisteredEventSchema = z.object({ artifactHash: frSchema, privateFunctionsRoot: frSchema, packedBytecode: bufferSchema, - artifactJson: z.any().optional(), + artifactJson: z.string().nullable().optional(), }); export type ChicmozL2ContractClassRegisteredEvent = z.infer< diff --git a/services/event-cannon/src/cannon/scenarios/deploy-and-run-simple-log.ts b/services/event-cannon/src/cannon/scenarios/deploy-and-run-simple-log.ts index 49ec0b67..ad777e14 100644 --- a/services/event-cannon/src/cannon/scenarios/deploy-and-run-simple-log.ts +++ b/services/event-cannon/src/cannon/scenarios/deploy-and-run-simple-log.ts @@ -1,8 +1,13 @@ import { DeploySentTx, waitForPXE } from "@aztec/aztec.js"; import { SimpleLoggingContract } from "../../artifacts/SimpleLogging.js"; +import SimpleLoggingContractArtifactJson from "../../contract-projects/SimpleLogging/target/simple_logging-SimpleLogging.json" assert { type: "json" }; import { logger } from "../../logger.js"; import { getAztecNodeClient, getPxe, getWallets } from "../pxe.js"; -import { deployContract, logAndWaitForTx } from "./utils/index.js"; +import { + deployContract, + logAndWaitForTx, + registerContractClassArtifact, +} from "./utils/index.js"; export async function run() { logger.info("===== SIMPLE LOG CONTRACT ====="); @@ -12,12 +17,24 @@ export async function run() { const deployerWallet = namedWallets.alice; + const contractLoggingName = "Voting Contract"; + const simpleLoggingContractDeployer = await deployContract({ - contractLoggingName: "Voting Contract", + contractLoggingName, deployFn: (): DeploySentTx => SimpleLoggingContract.deploy(deployerWallet).send(), node: getAztecNodeClient(), }); + + await new Promise((resolve) => setTimeout(resolve, 1000)); + + await registerContractClassArtifact( + contractLoggingName, + SimpleLoggingContractArtifactJson, + simpleLoggingContractDeployer.instance.contractClassId.toString(), + simpleLoggingContractDeployer.instance.version + ); + await logAndWaitForTx( simpleLoggingContractDeployer.methods.increase_counter_public(1).send(), "Increase counter public" diff --git a/services/event-cannon/src/cannon/scenarios/simple-deploy-contract.ts b/services/event-cannon/src/cannon/scenarios/simple-deploy-contract.ts index 42f3b163..f60249a1 100644 --- a/services/event-cannon/src/cannon/scenarios/simple-deploy-contract.ts +++ b/services/event-cannon/src/cannon/scenarios/simple-deploy-contract.ts @@ -3,6 +3,7 @@ import { logger } from "../../logger.js"; import { getAztecNodeClient, getPxe, getWallets } from "../pxe.js"; import { deployContract } from "./utils/index.js"; import { EasyPrivateVotingContract } from "@aztec/noir-contracts.js/EasyPrivateVoting"; +//import EasyPrivateVotingContractArtifactJson from "@aztec/noir-contracts.js/artifacts/easy_private_voting_contract-EasyPrivateVoting.json" assert { type: "json" }; export async function run() { logger.info("===== SIMPLE DEPLOY CONTRACT ====="); @@ -23,7 +24,4 @@ export async function run() { deployFn: (): DeploySentTx => sentTx, node: getAztecNodeClient(), }); - - // TODO: 1. try to get the contract in explorer-api - // TODO: 2. try to verify the contract class code in explorer-api } diff --git a/services/event-cannon/src/cannon/scenarios/utils/index.ts b/services/event-cannon/src/cannon/scenarios/utils/index.ts index 4b125a2d..d3e9ab2c 100644 --- a/services/event-cannon/src/cannon/scenarios/utils/index.ts +++ b/services/event-cannon/src/cannon/scenarios/utils/index.ts @@ -9,6 +9,7 @@ import { DeploySentTx, Fr, FunctionSelector, + NoirCompiledContract, PXE, SentTx, Wallet, @@ -22,6 +23,8 @@ import { import { deriveSigningKey } from "@aztec/circuits.js"; import { FunctionType } from "@aztec/foundation/abi"; import { ContractClassRegisteredEvent } from "@aztec/protocol-contracts/class-registerer"; +import { request } from "http"; +import { EXPLORER_API_URL } from "../../../environment.js"; import { logger } from "../../../logger.js"; export const truncateHashString = (value: string) => { @@ -207,3 +210,67 @@ export const publicDeployAccounts = async ( ]); await batch.send().wait(); }; + +export const registerContractClassArtifact = async ( + contractLoggingName: string, + artifactJson: object, + contractClassId: string, + version: number +) => { + const url = new URL( + `${EXPLORER_API_URL}/l2/contract-classes/${contractClassId}/versions/${version}` + ); + + const postData = JSON.stringify({ + stringifiedArtifactJson: JSON.stringify( + artifactJson as unknown as NoirCompiledContract + ), + }); + + const sizeInMB = Buffer.byteLength(postData) / 1000 ** 2; + if (sizeInMB > 1) { + logger.warn( + `🚨📜 ${contractLoggingName} Artifact is too large to register in explorer-api: ${url.href} (byte length: ${sizeInMB} MB)` + ); + return; + } + logger.info( + `📜 ${contractLoggingName} Trying to register artifact in explorer-api: ${url.href} (byte length: ${sizeInMB} MB)` + ); + await new Promise((resolve, reject) => { + const req = request( + url, + { + method: "POST", + headers: { + "Content-Type": "application/json", + "Content-Length": Buffer.byteLength(postData), + }, + }, + (res) => { + let data = ""; + res.on("data", (chunk) => { + data += chunk; + }); + res.on("end", () => { + resolve(JSON.parse(data)); + }); + } + ); + req.on("error", (error) => { + logger.error(`🚨📜 ${contractLoggingName} Artifact registration failed.`); + reject(error); + }); + + // Set a timeout (e.g., 5 seconds) + req.setTimeout(5000, () => { + reject(new Error("Request timed out")); + }); + + req.write(postData); + req.end(); // This actually sends the request + }); + logger.info( + `📜✅ ${contractLoggingName} Artifact registered in explorer-api.` + ); +}; diff --git a/services/event-cannon/src/environment.ts b/services/event-cannon/src/environment.ts index 273c955a..c5ce182e 100644 --- a/services/event-cannon/src/environment.ts +++ b/services/event-cannon/src/environment.ts @@ -1,4 +1,6 @@ export const NODE_ENV = process.env.NODE_ENV ?? "development"; export const SERVICE_NAME = process.env.SERVICE_NAME ?? "event-cannon"; + export const AZTEC_RPC_URL = process.env.AZTEC_RPC_URL ?? "http://aztec-sandbox-node.localhost"; export const ETHEREUM_RPC_URL = process.env.ETHEREUM_RPC_URL ?? "http://anvil-ethereum-node.localhost"; +export const EXPLORER_API_URL = process.env.EXPLORER_API_URL ?? "http://explorer-api.localhost/v1/d1e2083a-660c-4314-a6f2-1d42f4b944f4"; diff --git a/services/explorer-api/migrations/0000_colorful_sway.sql b/services/explorer-api/migrations/0000_mute_kinsey_walden.sql similarity index 99% rename from services/explorer-api/migrations/0000_colorful_sway.sql rename to services/explorer-api/migrations/0000_mute_kinsey_walden.sql index 0d0caa50..fef094ca 100644 --- a/services/explorer-api/migrations/0000_colorful_sway.sql +++ b/services/explorer-api/migrations/0000_mute_kinsey_walden.sql @@ -165,7 +165,7 @@ CREATE TABLE IF NOT EXISTS "l2_contract_class_registered" ( "artifact_hash" varchar(66) NOT NULL, "private_functions_root" varchar(66) NOT NULL, "packed_bytecode" "bytea" NOT NULL, - "artifact_json" jsonb, + "artifact_json" varchar, CONSTRAINT "contract_class_id_version" PRIMARY KEY("contract_class_id","version") ); --> statement-breakpoint diff --git a/services/explorer-api/migrations/meta/0000_snapshot.json b/services/explorer-api/migrations/meta/0000_snapshot.json index 5512bc96..40a24cdf 100644 --- a/services/explorer-api/migrations/meta/0000_snapshot.json +++ b/services/explorer-api/migrations/meta/0000_snapshot.json @@ -1,5 +1,5 @@ { - "id": "9c1c478b-6ab4-468c-9d51-8aa9e0f5631b", + "id": "b27f92b9-ee4f-47f1-8176-319856f9d1eb", "prevId": "00000000-0000-0000-0000-000000000000", "version": "7", "dialect": "postgresql", @@ -1056,7 +1056,7 @@ }, "artifact_json": { "name": "artifact_json", - "type": "jsonb", + "type": "varchar", "primaryKey": false, "notNull": false } diff --git a/services/explorer-api/migrations/meta/_journal.json b/services/explorer-api/migrations/meta/_journal.json index a2c05852..87887559 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": 1736245534764, - "tag": "0000_colorful_sway", + "when": 1736261271347, + "tag": "0000_mute_kinsey_walden", "breakpoints": true } ] diff --git a/services/explorer-api/src/database/controllers/l2contract/get-registered-contract-class.ts b/services/explorer-api/src/database/controllers/l2contract/get-registered-contract-class.ts index 0f4915ac..dde01042 100644 --- a/services/explorer-api/src/database/controllers/l2contract/get-registered-contract-class.ts +++ b/services/explorer-api/src/database/controllers/l2contract/get-registered-contract-class.ts @@ -2,7 +2,7 @@ import { chicmozL2ContractClassRegisteredEventSchema, type ChicmozL2ContractClassRegisteredEvent, } from "@chicmoz-pkg/types"; -import { and, desc, eq } from "drizzle-orm"; +import { and, desc, eq, getTableColumns } from "drizzle-orm"; import { DB_MAX_CONTRACTS } from "../../../environment.js"; import { getDb as db } from "../../../database/index.js"; import { l2ContractClassRegistered } from "../../schema/l2contract/index.js"; @@ -32,14 +32,7 @@ export const getL2RegisteredContractClasses = async ( const limit = version ? 1 : DB_MAX_CONTRACTS; const result = await db() - .select({ - blockHash: l2ContractClassRegistered.blockHash, - contractClassId: l2ContractClassRegistered.contractClassId, - version: l2ContractClassRegistered.version, - artifactHash: l2ContractClassRegistered.artifactHash, - privateFunctionsRoot: l2ContractClassRegistered.privateFunctionsRoot, - packedBytecode: l2ContractClassRegistered.packedBytecode, - }) + .select(getTableColumns(l2ContractClassRegistered)) .from(l2ContractClassRegistered) .where(whereQuery) .limit(limit) diff --git a/services/explorer-api/src/database/controllers/l2contract/store.ts b/services/explorer-api/src/database/controllers/l2contract/store.ts index e2177bfa..73e4f6ee 100644 --- a/services/explorer-api/src/database/controllers/l2contract/store.ts +++ b/services/explorer-api/src/database/controllers/l2contract/store.ts @@ -11,6 +11,8 @@ import { l2PrivateFunction, l2UnconstrainedFunction, } from "../../../database/schema/l2contract/index.js"; +import { and, eq } from "drizzle-orm"; +import {logger} from "../../../logger.js"; export const storeContractInstance = async ( instance: ChicmozL2ContractInstanceDeployedEvent @@ -62,6 +64,24 @@ export const storeContractClass = async ( }); }; +export const addArtifactJson = async ( + contractClassId: string, + version: number, + artifactJson: string +): Promise => { + logger.info(`Adding artifactJson for contractClassId: ${contractClassId}, version: ${version}`); + await db() + .update(l2ContractClassRegistered) + .set({ artifactJson }) + .where( + and( + eq(l2ContractClassRegistered.contractClassId, contractClassId), + eq(l2ContractClassRegistered.version, version) + ) + ) + .execute(); +}; + export const storePrivateFunction = async ( privateFunctionBroadcast: ChicmozL2PrivateFunctionBroadcastedEvent ): Promise => { diff --git a/services/explorer-api/src/database/schema/l2contract/index.ts b/services/explorer-api/src/database/schema/l2contract/index.ts index 04bd1996..303f27ba 100644 --- a/services/explorer-api/src/database/schema/l2contract/index.ts +++ b/services/explorer-api/src/database/schema/l2contract/index.ts @@ -108,7 +108,7 @@ export const l2ContractClassRegistered = pgTable( artifactHash: generateFrColumn("artifact_hash").notNull(), privateFunctionsRoot: generateFrColumn("private_functions_root").notNull(), packedBytecode: bufferType("packed_bytecode").notNull(), - artifactJson: jsonb("artifact_json"), + artifactJson: varchar("artifact_json"), }, (t) => ({ primaryKey: primaryKey({ diff --git a/services/explorer-api/src/environment.ts b/services/explorer-api/src/environment.ts index 9d1c2e1d..41b7c881 100644 --- a/services/explorer-api/src/environment.ts +++ b/services/explorer-api/src/environment.ts @@ -22,7 +22,7 @@ export const REDIS_HOST = process.env.REDIS_HOST ?? "redis-master"; export const REDIS_PORT = Number(process.env.REDIS_PORT) || 6379; export const PORT = Number(process.env.PORT) || 5000; -export const BODY_LIMIT = process.env.BODY_LIMIT ?? "64kb"; +export const BODY_LIMIT = process.env.BODY_LIMIT ?? "1MB"; // NOTE: this (high) is for contract class artifacts export const PARAMETER_LIMIT = Number(process.env.PARAMETER_LIMIT) || 100; export const DB_MAX_BLOCKS = 20; diff --git a/services/explorer-api/src/http-server/routes/controllers/contract-classes.ts b/services/explorer-api/src/http-server/routes/controllers/contract-classes.ts index 46c95f16..b5fd889e 100644 --- a/services/explorer-api/src/http-server/routes/controllers/contract-classes.ts +++ b/services/explorer-api/src/http-server/routes/controllers/contract-classes.ts @@ -16,7 +16,6 @@ import { dbWrapper, } from "./utils/index.js"; import { chicmozL2ContractClassRegisteredEventSchema } from "@chicmoz-pkg/types"; -import { logger } from "../../../logger.js"; export const openapi_GET_L2_REGISTERED_CONTRACT_CLASS = { "/l2/contract-classes/{classId}/versions/{version}": { @@ -158,22 +157,21 @@ export const POST_L2_REGISTERED_CONTRACT_CLASS_ARTIFACT = asyncHandler( ["l2", "contract-classes", classId, version], () => db.l2Contract.getL2RegisteredContractClass(classId, version) ); - //ChicmozL2ContractClassRegisteredEvent - const contractClass = - chicmozL2ContractClassRegisteredEventSchema.parse(contractClassString); + const contractClass = chicmozL2ContractClassRegisteredEventSchema.parse( + JSON.parse(contractClassString) + ); const uploadedArtifact = getContractClassFromArtifact( - loadContractArtifact( - stringifiedArtifactJson as unknown as NoirCompiledContract - ) + loadContractArtifact(JSON.parse(stringifiedArtifactJson) as unknown as NoirCompiledContract) + ); + const isMatchingByteCode = uploadedArtifact.packedBytecode.equals( + contractClass.packedBytecode ); - const isCorrectArtifact = - uploadedArtifact.packedBytecode === contractClass.packedBytecode; - logger.info(`🔍🔍🔍🔍🔍🔍🔍🔍🔍🔍🔍🔍 - ${uploadedArtifact.packedBytecode.toString()} - ${contractClass.packedBytecode.toString()} - ${isCorrectArtifact} - `); - if (!isCorrectArtifact) throw new Error("Incorrect artifact"); - res.status(200).send(isCorrectArtifact); + if (!isMatchingByteCode) throw new Error("Incorrect artifact"); + const completeContractClass = { + ...contractClass, + artifactJson: stringifiedArtifactJson, + }; + await db.l2Contract.addArtifactJson(contractClass.contractClassId, contractClass.version, stringifiedArtifactJson); + res.status(200).send(completeContractClass); } ); diff --git a/services/explorer-api/src/http-server/routes/index.ts b/services/explorer-api/src/http-server/routes/index.ts index 6fe99b16..ef87f2c7 100644 --- a/services/explorer-api/src/http-server/routes/index.ts +++ b/services/explorer-api/src/http-server/routes/index.ts @@ -100,6 +100,8 @@ export const init = ({ router }: { router: Router }) => { router.get(paths.contractClassUnconstrainedFunctions, controller.GET_L2_CONTRACT_CLASS_UNCONSTRAINED_FUNCTIONS); router.get(paths.contractClassUnconstrainedFunction, controller.GET_L2_CONTRACT_CLASS_UNCONSTRAINED_FUNCTION); + router.post(paths.contractClass, controller.POST_L2_REGISTERED_CONTRACT_CLASS_ARTIFACT); + router.get(paths.contractInstancesByBlockHash, controller.GET_L2_CONTRACT_INSTANCES_BY_BLOCK_HASH); router.get(paths.contractInstancesByContractClassId, controller.GET_L2_CONTRACT_INSTANCES_BY_CONTRACT_CLASS_ID); router.get(paths.contractInstance, controller.GET_L2_CONTRACT_INSTANCE); 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 72e3a9c9..f8ae7034 100644 --- a/services/explorer-ui/src/pages/contract-class-details/index.tsx +++ b/services/explorer-ui/src/pages/contract-class-details/index.tsx @@ -222,6 +222,9 @@ export const ContractClassDetails: FC = () => { )}
)} + { + // TODO: add artifactJson + } From ccbaea53453e1e2165702b57894e9560e9e809b6 Mon Sep 17 00:00:00 2001 From: filip Date: Wed, 8 Jan 2025 10:04:12 +0100 Subject: [PATCH 05/11] improved event-cannon --- services/event-cannon/src/cannon/index.ts | 12 +++---- .../deploy-and-interact-token-contract.ts | 19 +++++++++-- .../deploy-and-interact-vote-contract.ts | 30 ++++++++++++----- .../scenarios/deploy-and-run-simple-log.ts | 20 ++++++------ .../scenarios/l1-l2-private-messaging.ts | 27 ++++++++++++++-- .../scenarios/l1-l2-public-messaging.ts | 32 ++++++++++++++++--- .../scenarios/simple-deploy-contract.ts | 22 ++++++++++--- .../src/cannon/scenarios/utils/index.ts | 5 ++- services/event-cannon/tsconfig.json | 2 +- 9 files changed, 130 insertions(+), 39 deletions(-) diff --git a/services/event-cannon/src/cannon/index.ts b/services/event-cannon/src/cannon/index.ts index 8ca523bf..a273553a 100644 --- a/services/event-cannon/src/cannon/index.ts +++ b/services/event-cannon/src/cannon/index.ts @@ -17,13 +17,13 @@ export async function init() { export const start = async () => { logger.info("Starting Cannon..."); const scenariosToRun = [ - //scenarios.deploySimpleDefaultAccount, - //scenarios.deployAndInteractTokenContract, - //scenarios.deployAndInteractFunctionsVote, - //scenarios.deploySimpleContract, + scenarios.deploySimpleDefaultAccount, + scenarios.deployAndInteractTokenContract, + scenarios.deployAndInteractFunctionsVote, + scenarios.deploySimpleContract, scenarios.deploySimpleLog, - //scenarios.l1L2PublicMessaging, - //scenarios.l1L2PrivateMessaging, + scenarios.l1L2PublicMessaging, + scenarios.l1L2PrivateMessaging, ] as (() => Promise)[]; for (const fn of scenariosToRun) await fn(); }; diff --git a/services/event-cannon/src/cannon/scenarios/deploy-and-interact-token-contract.ts b/services/event-cannon/src/cannon/scenarios/deploy-and-interact-token-contract.ts index 0eb7d436..f8e06a3a 100644 --- a/services/event-cannon/src/cannon/scenarios/deploy-and-interact-token-contract.ts +++ b/services/event-cannon/src/cannon/scenarios/deploy-and-interact-token-contract.ts @@ -1,8 +1,13 @@ import { Contract, DeploySentTx, waitForPXE } from "@aztec/aztec.js"; import { logger } from "../../logger.js"; import { getAztecNodeClient, getPxe, getWallets } from "../pxe.js"; -import { deployContract, logAndWaitForTx } from "./utils/index.js"; +import { + deployContract, + logAndWaitForTx, + registerContractClassArtifact, +} from "./utils/index.js"; import { TokenContract } from "@aztec/noir-contracts.js/Token"; +import * as tokenContractArtifactJson from "@aztec/noir-contracts.js/artifacts/token_contract-Token" assert { type: "json" }; export async function run() { logger.info("===== TOKEN CONTRACT ====="); @@ -13,8 +18,9 @@ export async function run() { const deployerWallet = namedWallets.alice; const tokenAdmin = namedWallets.alice.getAddress(); + const contractLoggingName = "Token Contract"; const tokenContract = await deployContract({ - contractLoggingName: "Token Contract", + contractLoggingName, deployFn: (): DeploySentTx => { return TokenContract.deploy( deployerWallet, @@ -27,6 +33,15 @@ export async function run() { node: getAztecNodeClient(), }); + registerContractClassArtifact( + contractLoggingName, + tokenContractArtifactJson, + tokenContract.instance.contractClassId.toString(), + tokenContract.instance.version + ).catch((err) => { + logger.error(err); + }); + await Promise.all([ logAndWaitForTx( tokenContract.methods diff --git a/services/event-cannon/src/cannon/scenarios/deploy-and-interact-vote-contract.ts b/services/event-cannon/src/cannon/scenarios/deploy-and-interact-vote-contract.ts index a57b0a0a..763e5385 100644 --- a/services/event-cannon/src/cannon/scenarios/deploy-and-interact-vote-contract.ts +++ b/services/event-cannon/src/cannon/scenarios/deploy-and-interact-vote-contract.ts @@ -1,11 +1,16 @@ import { Contract, DeploySentTx, Fr, waitForPXE } from "@aztec/aztec.js"; import { logger } from "../../logger.js"; import { getAztecNodeClient, getPxe, getWallets } from "../pxe.js"; -import { deployContract, logAndWaitForTx } from "./utils/index.js"; +import { + deployContract, + logAndWaitForTx, + registerContractClassArtifact, +} from "./utils/index.js"; import { EasyPrivateVotingContract, EasyPrivateVotingContractArtifact, } from "@aztec/noir-contracts.js/EasyPrivateVoting"; +import * as contractArtifactJson from "@aztec/noir-contracts.js/artifacts/easy_private_voting_contract-EasyPrivateVoting" assert { type: "json" }; export async function run() { logger.info("===== VOTING CONTRACT ====="); @@ -16,26 +21,35 @@ export async function run() { const deployerWallet = namedWallets.alice; const votingAdmin = namedWallets.alice.getAddress(); - const votingContractDeployer = await deployContract({ - contractLoggingName: "Voting Contract", + const contractLoggingName = "Voting Contract"; + const contract = await deployContract({ + contractLoggingName, deployFn: (): DeploySentTx => EasyPrivateVotingContract.deploy(deployerWallet, votingAdmin).send(), broadcastWithWallet: deployerWallet, // NOTE: comment this out to not broadcast node: getAztecNodeClient(), }); + registerContractClassArtifact( + contractLoggingName, + contractArtifactJson, + contract.instance.contractClassId.toString(), + contract.instance.version + ).catch((err) => { + logger.error(err); + }); const votingContractAlice = await Contract.at( - votingContractDeployer.address, + contract.address, EasyPrivateVotingContractArtifact, namedWallets.alice ); const votingContractBob = await Contract.at( - votingContractDeployer.address, + contract.address, EasyPrivateVotingContractArtifact, namedWallets.bob ); const votingContractCharlie = await Contract.at( - votingContractDeployer.address, + contract.address, EasyPrivateVotingContractArtifact, namedWallets.charlie ); @@ -58,10 +72,10 @@ export async function run() { ), ]); - const votesA = (await votingContractDeployer.methods + const votesA = (await contract.methods .get_vote(candidateA) .simulate()) as bigint; - const votesB = (await votingContractDeployer.methods + const votesB = (await contract.methods .get_vote(candidateB) .simulate()) as bigint; diff --git a/services/event-cannon/src/cannon/scenarios/deploy-and-run-simple-log.ts b/services/event-cannon/src/cannon/scenarios/deploy-and-run-simple-log.ts index ad777e14..810e98fc 100644 --- a/services/event-cannon/src/cannon/scenarios/deploy-and-run-simple-log.ts +++ b/services/event-cannon/src/cannon/scenarios/deploy-and-run-simple-log.ts @@ -1,6 +1,6 @@ import { DeploySentTx, waitForPXE } from "@aztec/aztec.js"; import { SimpleLoggingContract } from "../../artifacts/SimpleLogging.js"; -import SimpleLoggingContractArtifactJson from "../../contract-projects/SimpleLogging/target/simple_logging-SimpleLogging.json" assert { type: "json" }; +import artifactJson from "../../contract-projects/SimpleLogging/target/simple_logging-SimpleLogging.json" assert { type: "json" }; import { logger } from "../../logger.js"; import { getAztecNodeClient, getPxe, getWallets } from "../pxe.js"; import { @@ -19,24 +19,24 @@ export async function run() { const contractLoggingName = "Voting Contract"; - const simpleLoggingContractDeployer = await deployContract({ + const contract = await deployContract({ contractLoggingName, deployFn: (): DeploySentTx => SimpleLoggingContract.deploy(deployerWallet).send(), node: getAztecNodeClient(), }); - await new Promise((resolve) => setTimeout(resolve, 1000)); - - await registerContractClassArtifact( + registerContractClassArtifact( contractLoggingName, - SimpleLoggingContractArtifactJson, - simpleLoggingContractDeployer.instance.contractClassId.toString(), - simpleLoggingContractDeployer.instance.version - ); + artifactJson, + contract.instance.contractClassId.toString(), + contract.instance.version + ).catch((err) => { + logger.error(err); + }); await logAndWaitForTx( - simpleLoggingContractDeployer.methods.increase_counter_public(1).send(), + contract.methods.increase_counter_public(1).send(), "Increase counter public" ); } diff --git a/services/event-cannon/src/cannon/scenarios/l1-l2-private-messaging.ts b/services/event-cannon/src/cannon/scenarios/l1-l2-private-messaging.ts index bbb16889..3e5b20c2 100644 --- a/services/event-cannon/src/cannon/scenarios/l1-l2-private-messaging.ts +++ b/services/event-cannon/src/cannon/scenarios/l1-l2-private-messaging.ts @@ -15,6 +15,7 @@ import { deployContract, logAndWaitForTx, publicDeployAccounts, + registerContractClassArtifact, } from "./utils/index.js"; import { createPublicClient, @@ -34,7 +35,9 @@ import { } from "@aztec/l1-artifacts"; import assert from "assert"; import { TokenContract } from "@aztec/noir-contracts.js/Token"; +import * as tokenContractArtifactJson from "@aztec/noir-contracts.js/artifacts/token_contract-Token" assert { type: "json" }; import { TokenBridgeContract } from "@aztec/noir-contracts.js/TokenBridge"; +import * as tokenBridgeContractArtifactJson from "@aztec/noir-contracts.js/artifacts/token_bridge_contract-TokenBridge" assert { type: "json" }; const MNEMONIC = "test test test test test test test test test test test junk"; const TOKEN_NAME = "TokenName"; @@ -90,8 +93,10 @@ export const run = async () => { }); const owner = wallet.getAddress(); + + const tokenContractLoggingName = "Token Contract"; const token = await deployContract({ - contractLoggingName: "Token Contract", + contractLoggingName: tokenContractLoggingName, deployFn: (): DeploySentTx => { return TokenContract.deploy( wallet, @@ -103,9 +108,18 @@ export const run = async () => { }, node: getAztecNodeClient(), }); + registerContractClassArtifact( + tokenContractLoggingName, + tokenContractArtifactJson, + token.instance.contractClassId.toString(), + token.instance.version + ).catch((err) => { + logger.error(err); + }); + const tokenBridgeContractLoggingName = "Token Bridge Contract"; const bridge = await deployContract({ - contractLoggingName: "Token Bridge Contract", + contractLoggingName: tokenBridgeContractLoggingName, deployFn: (): DeploySentTx => { return TokenBridgeContract.deploy( wallet, @@ -116,6 +130,15 @@ export const run = async () => { node: getAztecNodeClient(), }); + registerContractClassArtifact( + tokenBridgeContractLoggingName, + tokenBridgeContractArtifactJson, + bridge.instance.contractClassId.toString(), + bridge.instance.version + ).catch((err) => { + logger.error(err); + }); + if ((await token.methods.get_admin().simulate()) !== owner.toBigInt()) throw new Error(`Token admin is not ${owner.toString()}`); diff --git a/services/event-cannon/src/cannon/scenarios/l1-l2-public-messaging.ts b/services/event-cannon/src/cannon/scenarios/l1-l2-public-messaging.ts index 7f574d7c..cc8c3c18 100644 --- a/services/event-cannon/src/cannon/scenarios/l1-l2-public-messaging.ts +++ b/services/event-cannon/src/cannon/scenarios/l1-l2-public-messaging.ts @@ -15,6 +15,7 @@ import { deployContract, logAndWaitForTx, publicDeployAccounts, + registerContractClassArtifact, } from "./utils/index.js"; import { createPublicClient, @@ -24,9 +25,7 @@ import { } from "viem"; import { mnemonicToAccount } from "viem/accounts"; import { foundry } from "viem/chains"; -import { - ETHEREUM_RPC_URL, -} from "../../environment.js"; +import { ETHEREUM_RPC_URL } from "../../environment.js"; import { RollupAbi, TestERC20Abi, @@ -36,7 +35,9 @@ import { } from "@aztec/l1-artifacts"; import assert from "assert"; import { TokenContract } from "@aztec/noir-contracts.js/Token"; +import * as tokenContractArtifactJson from "@aztec/noir-contracts.js/artifacts/token_contract-Token" assert { type: "json" }; import { TokenBridgeContract } from "@aztec/noir-contracts.js/TokenBridge"; +import * as tokenBridgeContractArtifactJson from "@aztec/noir-contracts.js/artifacts/token_bridge_contract-TokenBridge" assert { type: "json" }; const MNEMONIC = "test test test test test test test test test test test junk"; const TOKEN_NAME = "TokenName"; @@ -95,8 +96,10 @@ export const run = async () => { }); const owner = wallet.getAddress(); + + const tokenContractLoggingName = "Token Contract"; const token = await deployContract({ - contractLoggingName: "Token Contract", + contractLoggingName: tokenContractLoggingName, deployFn: (): DeploySentTx => { return TokenContract.deploy( wallet, @@ -109,8 +112,18 @@ export const run = async () => { node: getAztecNodeClient(), }); + registerContractClassArtifact( + tokenContractLoggingName, + tokenContractArtifactJson, + token.instance.contractClassId.toString(), + token.instance.version + ).catch((err) => { + logger.error(err); + }); + + const tokenBridgeContractLoggingName = "Token Bridge Contract"; const bridge = await deployContract({ - contractLoggingName: "Token Bridge Contract", + contractLoggingName: tokenBridgeContractLoggingName, deployFn: (): DeploySentTx => { return TokenBridgeContract.deploy( wallet, @@ -121,6 +134,15 @@ export const run = async () => { node: getAztecNodeClient(), }); + registerContractClassArtifact( + tokenBridgeContractLoggingName, + tokenBridgeContractArtifactJson, + bridge.instance.contractClassId.toString(), + bridge.instance.version + ).catch((err) => { + logger.error(err); + }); + if ((await token.methods.get_admin().simulate()) !== owner.toBigInt()) throw new Error(`Token admin is not ${owner.toString()}`); diff --git a/services/event-cannon/src/cannon/scenarios/simple-deploy-contract.ts b/services/event-cannon/src/cannon/scenarios/simple-deploy-contract.ts index f60249a1..8925235a 100644 --- a/services/event-cannon/src/cannon/scenarios/simple-deploy-contract.ts +++ b/services/event-cannon/src/cannon/scenarios/simple-deploy-contract.ts @@ -1,9 +1,12 @@ import { DeploySentTx, waitForPXE } from "@aztec/aztec.js"; import { logger } from "../../logger.js"; import { getAztecNodeClient, getPxe, getWallets } from "../pxe.js"; -import { deployContract } from "./utils/index.js"; +import { + deployContract, + registerContractClassArtifact, +} from "./utils/index.js"; import { EasyPrivateVotingContract } from "@aztec/noir-contracts.js/EasyPrivateVoting"; -//import EasyPrivateVotingContractArtifactJson from "@aztec/noir-contracts.js/artifacts/easy_private_voting_contract-EasyPrivateVoting.json" assert { type: "json" }; +import * as contractArtifactJson from "@aztec/noir-contracts.js/artifacts/easy_private_voting_contract-EasyPrivateVoting" assert { type: "json" }; export async function run() { logger.info("===== SIMPLE DEPLOY CONTRACT ====="); @@ -19,9 +22,20 @@ export async function run() { votingAdmin ).send(); - await deployContract({ - contractLoggingName: "Voting Contract", + const contractLoggingName = "Voting Contract"; + + const contract = await deployContract({ + contractLoggingName, deployFn: (): DeploySentTx => sentTx, node: getAztecNodeClient(), }); + + registerContractClassArtifact( + contractLoggingName, + contractArtifactJson, + contract.instance.contractClassId.toString(), + contract.instance.version + ).catch((err) => { + logger.error(err); + }); } diff --git a/services/event-cannon/src/cannon/scenarios/utils/index.ts b/services/event-cannon/src/cannon/scenarios/utils/index.ts index d3e9ab2c..511f8b70 100644 --- a/services/event-cannon/src/cannon/scenarios/utils/index.ts +++ b/services/event-cannon/src/cannon/scenarios/utils/index.ts @@ -215,7 +215,8 @@ export const registerContractClassArtifact = async ( contractLoggingName: string, artifactJson: object, contractClassId: string, - version: number + version: number, + skipSleep = false ) => { const url = new URL( `${EXPLORER_API_URL}/l2/contract-classes/${contractClassId}/versions/${version}` @@ -237,6 +238,8 @@ export const registerContractClassArtifact = async ( logger.info( `📜 ${contractLoggingName} Trying to register artifact in explorer-api: ${url.href} (byte length: ${sizeInMB} MB)` ); + if (!skipSleep) await new Promise((resolve) => setTimeout(resolve, 1000)); + await new Promise((resolve, reject) => { const req = request( url, diff --git a/services/event-cannon/tsconfig.json b/services/event-cannon/tsconfig.json index 73768f93..82979443 100644 --- a/services/event-cannon/tsconfig.json +++ b/services/event-cannon/tsconfig.json @@ -17,7 +17,7 @@ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ "resolveJsonModule": true /* Enable importing .json files. */, - // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + "allowArbitraryExtensions": true /* Enable importing files with any extension, provided a declaration file is present. */, // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ /* JavaScript Support */ // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ From a8151ce56afe752d36f1052610a5ad0d886995dd Mon Sep 17 00:00:00 2001 From: filip Date: Wed, 8 Jan 2025 10:20:05 +0100 Subject: [PATCH 06/11] done --- .../src/cannon/scenarios/utils/index.ts | 2 +- services/explorer-api/src/environment.ts | 3 +- .../routes/controllers/contract-classes.ts | 31 +++++++++++++++++-- .../src/http-server/routes/index.ts | 10 +++++- 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/services/event-cannon/src/cannon/scenarios/utils/index.ts b/services/event-cannon/src/cannon/scenarios/utils/index.ts index 511f8b70..746cda08 100644 --- a/services/event-cannon/src/cannon/scenarios/utils/index.ts +++ b/services/event-cannon/src/cannon/scenarios/utils/index.ts @@ -229,7 +229,7 @@ export const registerContractClassArtifact = async ( }); const sizeInMB = Buffer.byteLength(postData) / 1000 ** 2; - if (sizeInMB > 1) { + if (sizeInMB > 10) { logger.warn( `🚨📜 ${contractLoggingName} Artifact is too large to register in explorer-api: ${url.href} (byte length: ${sizeInMB} MB)` ); diff --git a/services/explorer-api/src/environment.ts b/services/explorer-api/src/environment.ts index 41b7c881..7133308d 100644 --- a/services/explorer-api/src/environment.ts +++ b/services/explorer-api/src/environment.ts @@ -22,7 +22,8 @@ export const REDIS_HOST = process.env.REDIS_HOST ?? "redis-master"; export const REDIS_PORT = Number(process.env.REDIS_PORT) || 6379; export const PORT = Number(process.env.PORT) || 5000; -export const BODY_LIMIT = process.env.BODY_LIMIT ?? "1MB"; // NOTE: this (high) is for contract class artifacts +export const BODY_LIMIT = process.env.BODY_LIMIT ?? "64kb"; +export const ARTIFACT_BODY_LIMIT = process.env.ARTIFACT_BODY_LIMIT ?? "10mb"; export const PARAMETER_LIMIT = Number(process.env.PARAMETER_LIMIT) || 100; export const DB_MAX_BLOCKS = 20; diff --git a/services/explorer-api/src/http-server/routes/controllers/contract-classes.ts b/services/explorer-api/src/http-server/routes/controllers/contract-classes.ts index b5fd889e..3996dc31 100644 --- a/services/explorer-api/src/http-server/routes/controllers/contract-classes.ts +++ b/services/explorer-api/src/http-server/routes/controllers/contract-classes.ts @@ -3,8 +3,12 @@ import { loadContractArtifact, type NoirCompiledContract, } from "@aztec/aztec.js"; +import { chicmozL2ContractClassRegisteredEventSchema } from "@chicmoz-pkg/types"; import asyncHandler from "express-async-handler"; +import { getCache } from "../../../cache/index.js"; import { controllers as db } from "../../../database/index.js"; +import { CACHE_TTL_SECONDS } from "../../../environment.js"; +import { logger } from "../../../logger.js"; import { getContractClassesByClassIdSchema, getContractClassSchema, @@ -15,7 +19,6 @@ import { contractClassResponseArray, dbWrapper, } from "./utils/index.js"; -import { chicmozL2ContractClassRegisteredEventSchema } from "@chicmoz-pkg/types"; export const openapi_GET_L2_REGISTERED_CONTRACT_CLASS = { "/l2/contract-classes/{classId}/versions/{version}": { @@ -160,8 +163,14 @@ export const POST_L2_REGISTERED_CONTRACT_CLASS_ARTIFACT = asyncHandler( const contractClass = chicmozL2ContractClassRegisteredEventSchema.parse( JSON.parse(contractClassString) ); + if (contractClass.artifactJson) { + res.status(200).send(contractClass); + return; + } const uploadedArtifact = getContractClassFromArtifact( - loadContractArtifact(JSON.parse(stringifiedArtifactJson) as unknown as NoirCompiledContract) + loadContractArtifact( + JSON.parse(stringifiedArtifactJson) as unknown as NoirCompiledContract + ) ); const isMatchingByteCode = uploadedArtifact.packedBytecode.equals( contractClass.packedBytecode @@ -171,7 +180,23 @@ export const POST_L2_REGISTERED_CONTRACT_CLASS_ARTIFACT = asyncHandler( ...contractClass, artifactJson: stringifiedArtifactJson, }; - await db.l2Contract.addArtifactJson(contractClass.contractClassId, contractClass.version, stringifiedArtifactJson); + getCache() + .set( + ["l2", "contract-classes", classId, version].join("-"), + JSON.stringify(completeContractClass), + { + EX: CACHE_TTL_SECONDS, + } + ) + .catch((err) => { + logger.warn(`Failed to cache contract class: ${err}`); + }); + await db.l2Contract.addArtifactJson( + contractClass.contractClassId, + contractClass.version, + stringifiedArtifactJson + ); + // TODO: update cache res.status(200).send(completeContractClass); } ); diff --git a/services/explorer-api/src/http-server/routes/index.ts b/services/explorer-api/src/http-server/routes/index.ts index ef87f2c7..7506a4fa 100644 --- a/services/explorer-api/src/http-server/routes/index.ts +++ b/services/explorer-api/src/http-server/routes/index.ts @@ -3,6 +3,8 @@ import * as controller from "./controllers/index.js"; import { paths } from "./paths_and_validation.js"; import assert from "assert"; import { logger } from "../../logger.js"; +import bodyParser from "body-parser"; +import {ARTIFACT_BODY_LIMIT} from "../../environment.js"; export const openApiPaths = { ...controller.openapi_GET_LATEST_HEIGHT, @@ -100,7 +102,13 @@ export const init = ({ router }: { router: Router }) => { router.get(paths.contractClassUnconstrainedFunctions, controller.GET_L2_CONTRACT_CLASS_UNCONSTRAINED_FUNCTIONS); router.get(paths.contractClassUnconstrainedFunction, controller.GET_L2_CONTRACT_CLASS_UNCONSTRAINED_FUNCTION); - router.post(paths.contractClass, controller.POST_L2_REGISTERED_CONTRACT_CLASS_ARTIFACT); + router.post( + paths.contractClass, + bodyParser.json({ + limit: ARTIFACT_BODY_LIMIT + }), + controller.POST_L2_REGISTERED_CONTRACT_CLASS_ARTIFACT + ); router.get(paths.contractInstancesByBlockHash, controller.GET_L2_CONTRACT_INSTANCES_BY_BLOCK_HASH); router.get(paths.contractInstancesByContractClassId, controller.GET_L2_CONTRACT_INSTANCES_BY_CONTRACT_CLASS_ID); From 2e0519fd4b8337e30f3043629e788cec5e22ad36 Mon Sep 17 00:00:00 2001 From: filip Date: Wed, 8 Jan 2025 10:37:53 +0100 Subject: [PATCH 07/11] done --- services/event-cannon/src/cannon/pxe.ts | 15 ----- .../routes/controllers/contract-classes.ts | 4 +- .../src/http-server/routes/index.ts | 67 ++++++++++++++----- 3 files changed, 53 insertions(+), 33 deletions(-) diff --git a/services/event-cannon/src/cannon/pxe.ts b/services/event-cannon/src/cannon/pxe.ts index 4cda78e0..6a0010c1 100644 --- a/services/event-cannon/src/cannon/pxe.ts +++ b/services/event-cannon/src/cannon/pxe.ts @@ -18,18 +18,8 @@ let namedWallets: { charlie: AccountWallet; } | null = null; -let version: string | null = null; - export const setup = async () => { aztecNode = createAztecNodeClient(AZTEC_RPC_URL); - const v = await aztecNode.getNodeVersion(); - if (v === "0.1.0") { - // TODO: this is a temporary workaround for the versioning issue - version = "0.69.0"; - } else { - logger.info(`Finally the getNodeVersion is working! ${v}`); - version = v; - } pxe = createPXEClient(AZTEC_RPC_URL); await waitForPXE(pxe); const info = await pxe.getPXEInfo(); @@ -42,11 +32,6 @@ export const setup = async () => { }; }; -export const getNodeVersion = () => { - if (!version) throw new Error("Version not initialized"); - return version; -} - export const getAztecNodeClient = () => { if (!aztecNode) throw new Error("Aztec Node not initialized"); return aztecNode; diff --git a/services/explorer-api/src/http-server/routes/controllers/contract-classes.ts b/services/explorer-api/src/http-server/routes/controllers/contract-classes.ts index 3996dc31..4f32c457 100644 --- a/services/explorer-api/src/http-server/routes/controllers/contract-classes.ts +++ b/services/explorer-api/src/http-server/routes/controllers/contract-classes.ts @@ -144,7 +144,6 @@ export const openapi_POST_L2_REGISTERED_CONTRACT_CLASS_ARTIFACT = { }, }, }, - // TODO: add response schema responses: contractClassResponse, }, }, @@ -196,7 +195,6 @@ export const POST_L2_REGISTERED_CONTRACT_CLASS_ARTIFACT = asyncHandler( contractClass.version, stringifiedArtifactJson ); - // TODO: update cache - res.status(200).send(completeContractClass); + res.status(201).send(completeContractClass); } ); diff --git a/services/explorer-api/src/http-server/routes/index.ts b/services/explorer-api/src/http-server/routes/index.ts index 7506a4fa..591cce24 100644 --- a/services/explorer-api/src/http-server/routes/index.ts +++ b/services/explorer-api/src/http-server/routes/index.ts @@ -4,7 +4,7 @@ import { paths } from "./paths_and_validation.js"; import assert from "assert"; import { logger } from "../../logger.js"; import bodyParser from "body-parser"; -import {ARTIFACT_BODY_LIMIT} from "../../environment.js"; +import { ARTIFACT_BODY_LIMIT } from "../../environment.js"; export const openApiPaths = { ...controller.openapi_GET_LATEST_HEIGHT, @@ -27,6 +27,8 @@ export const openApiPaths = { ...controller.openapi_GET_L2_CONTRACT_CLASS_UNCONSTRAINED_FUNCTIONS, ...controller.openapi_GET_L2_CONTRACT_CLASS_UNCONSTRAINED_FUNCTION, + ...controller.openapi_POST_L2_REGISTERED_CONTRACT_CLASS_ARTIFACT, + ...controller.openapi_GET_L2_CONTRACT_INSTANCES_BY_BLOCK_HASH, ...controller.openapi_GET_L2_CONTRACT_INSTANCES_BY_CONTRACT_CLASS_ID, ...controller.openapi_GET_L2_CONTRACT_INSTANCE, @@ -73,9 +75,11 @@ const checkDocsStatus = () => { assert(totalPaths - totalStatsPaths === totalOpenApiPaths); } catch (e) { // eslint-disable-next-line @typescript-eslint/restrict-template-expressions - logger.error(`STARTING SERVER WITHOUT SUFFICIENT DOCS! ${totalPaths} - ${totalStatsPaths} !== ${totalOpenApiPaths}`); + logger.error( + `STARTING SERVER WITHOUT SUFFICIENT DOCS! ${totalPaths} - ${totalStatsPaths} !== ${totalOpenApiPaths}` + ); } -} +}; export const init = ({ router }: { router: Router }) => { checkDocsStatus(); @@ -87,31 +91,64 @@ export const init = ({ router }: { router: Router }) => { router.get(paths.block, controller.GET_BLOCK); router.get(paths.blocks, controller.GET_BLOCKS); - router.get(paths.txEffectsByBlockHeight, controller.GET_L2_TX_EFFECTS_BY_BLOCK_HEIGHT); - router.get(paths.txEffectByBlockHeightAndIndex, controller.GET_L2_TX_EFFECT_BY_BLOCK_HEIGHT_AND_INDEX); - router.get(paths.txEffectsByTxEffectHash, controller.GET_L2_TX_EFFECT_BY_TX_EFFECT_HASH); + router.get( + paths.txEffectsByBlockHeight, + controller.GET_L2_TX_EFFECTS_BY_BLOCK_HEIGHT + ); + router.get( + paths.txEffectByBlockHeightAndIndex, + controller.GET_L2_TX_EFFECT_BY_BLOCK_HEIGHT_AND_INDEX + ); + router.get( + paths.txEffectsByTxEffectHash, + controller.GET_L2_TX_EFFECT_BY_TX_EFFECT_HASH + ); router.get(paths.txs, controller.GET_PENDING_TXS); router.get(paths.contractClass, controller.GET_L2_REGISTERED_CONTRACT_CLASS); - router.get(paths.contractClassesByClassId, controller.GET_L2_REGISTERED_CONTRACT_CLASSES_ALL_VERSIONS); - router.get(paths.contractClasses, controller.GET_L2_REGISTERED_CONTRACT_CLASSES); + router.get( + paths.contractClassesByClassId, + controller.GET_L2_REGISTERED_CONTRACT_CLASSES_ALL_VERSIONS + ); + router.get( + paths.contractClasses, + controller.GET_L2_REGISTERED_CONTRACT_CLASSES + ); - router.get(paths.contractClassPrivateFunctions, controller.GET_L2_CONTRACT_CLASS_PRIVATE_FUNCTIONS); - router.get(paths.contractClassPrivateFunction, controller.GET_L2_CONTRACT_CLASS_PRIVATE_FUNCTION); - router.get(paths.contractClassUnconstrainedFunctions, controller.GET_L2_CONTRACT_CLASS_UNCONSTRAINED_FUNCTIONS); - router.get(paths.contractClassUnconstrainedFunction, controller.GET_L2_CONTRACT_CLASS_UNCONSTRAINED_FUNCTION); + router.get( + paths.contractClassPrivateFunctions, + controller.GET_L2_CONTRACT_CLASS_PRIVATE_FUNCTIONS + ); + router.get( + paths.contractClassPrivateFunction, + controller.GET_L2_CONTRACT_CLASS_PRIVATE_FUNCTION + ); + router.get( + paths.contractClassUnconstrainedFunctions, + controller.GET_L2_CONTRACT_CLASS_UNCONSTRAINED_FUNCTIONS + ); + router.get( + paths.contractClassUnconstrainedFunction, + controller.GET_L2_CONTRACT_CLASS_UNCONSTRAINED_FUNCTION + ); router.post( paths.contractClass, bodyParser.json({ - limit: ARTIFACT_BODY_LIMIT + limit: ARTIFACT_BODY_LIMIT, }), controller.POST_L2_REGISTERED_CONTRACT_CLASS_ARTIFACT ); - router.get(paths.contractInstancesByBlockHash, controller.GET_L2_CONTRACT_INSTANCES_BY_BLOCK_HASH); - router.get(paths.contractInstancesByContractClassId, controller.GET_L2_CONTRACT_INSTANCES_BY_CONTRACT_CLASS_ID); + router.get( + paths.contractInstancesByBlockHash, + controller.GET_L2_CONTRACT_INSTANCES_BY_BLOCK_HASH + ); + router.get( + paths.contractInstancesByContractClassId, + controller.GET_L2_CONTRACT_INSTANCES_BY_CONTRACT_CLASS_ID + ); router.get(paths.contractInstance, controller.GET_L2_CONTRACT_INSTANCE); router.get(paths.contractInstances, controller.GET_L2_CONTRACT_INSTANCES); From a9e54ccf13bdef270951a0f8aa3846483fd729e0 Mon Sep 17 00:00:00 2001 From: filip Date: Wed, 8 Jan 2025 10:38:52 +0100 Subject: [PATCH 08/11] done --- .../explorer-api/src/database/controllers/l2contract/store.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/services/explorer-api/src/database/controllers/l2contract/store.ts b/services/explorer-api/src/database/controllers/l2contract/store.ts index 73e4f6ee..d208145e 100644 --- a/services/explorer-api/src/database/controllers/l2contract/store.ts +++ b/services/explorer-api/src/database/controllers/l2contract/store.ts @@ -12,7 +12,6 @@ import { l2UnconstrainedFunction, } from "../../../database/schema/l2contract/index.js"; import { and, eq } from "drizzle-orm"; -import {logger} from "../../../logger.js"; export const storeContractInstance = async ( instance: ChicmozL2ContractInstanceDeployedEvent @@ -69,7 +68,6 @@ export const addArtifactJson = async ( version: number, artifactJson: string ): Promise => { - logger.info(`Adding artifactJson for contractClassId: ${contractClassId}, version: ${version}`); await db() .update(l2ContractClassRegistered) .set({ artifactJson }) From 462542c060b7938a7137d8481dacaf5e74039c20 Mon Sep 17 00:00:00 2001 From: filip Date: Wed, 8 Jan 2025 12:26:12 +0100 Subject: [PATCH 09/11] done --- packages/types/src/aztec/special.ts | 10 ++-- services/explorer-api/src/constants.ts | 12 ++--- .../database/controllers/l2contract/utils.ts | 4 +- services/explorer-api/src/environment.ts | 10 ++-- .../http-server/routes/controllers/index.ts | 2 +- .../controllers/utils/open-api-responses.ts | 6 +-- .../verified-contract-instances.ts | 49 +++++++++++++++++++ .../routes/controllers/verified-contracts.ts | 49 ------------------- .../src/http-server/routes/index.ts | 8 +-- .../routes/paths_and_validation.ts | 6 +-- services/explorer-ui/src/api/index.ts | 2 +- ...tract.ts => verified-contract-instance.ts} | 14 +++--- .../src/hooks/verified-contract-instance.ts | 14 ++++++ .../src/hooks/verified-contract.ts | 14 ------ .../pages/contract-instance-details/index.tsx | 14 +++--- .../pages/contract-instance-details/util.ts | 4 +- ...ts.tsx => verified-contract-instances.tsx} | 18 +++---- services/explorer-ui/src/routeTree.gen.ts | 35 +++++++------ services/explorer-ui/src/routes/__root.tsx | 6 +-- .../verified-contract-instances.lazy.tsx | 6 +++ .../src/routes/verified-contracts.lazy.tsx | 6 --- 21 files changed, 146 insertions(+), 143 deletions(-) create mode 100644 services/explorer-api/src/http-server/routes/controllers/verified-contract-instances.ts delete mode 100644 services/explorer-api/src/http-server/routes/controllers/verified-contracts.ts rename services/explorer-ui/src/api/{verified-contract.ts => verified-contract-instance.ts} (61%) create mode 100644 services/explorer-ui/src/hooks/verified-contract-instance.ts delete mode 100644 services/explorer-ui/src/hooks/verified-contract.ts rename services/explorer-ui/src/pages/{verified-contracts.tsx => verified-contract-instances.tsx} (77%) create mode 100644 services/explorer-ui/src/routes/verified-contract-instances.lazy.tsx delete mode 100644 services/explorer-ui/src/routes/verified-contracts.lazy.tsx diff --git a/packages/types/src/aztec/special.ts b/packages/types/src/aztec/special.ts index 07e8e87f..493723a3 100644 --- a/packages/types/src/aztec/special.ts +++ b/packages/types/src/aztec/special.ts @@ -6,8 +6,8 @@ import { } from "./l2Contract.js"; import { chicmozL2TxEffectSchema } from "./l2TxEffect.js"; -export const chicmozL2VerifiedContractAddressDataSchema = z.object({ - contractInstanceAddress: z.string(), +export const chicmozL2VerifiedContractInstanceDataSchema = z.object({ + address: z.lazy(() => chicmozL2ContractInstanceDeployedEventSchema.shape.address), contractIdentifier: z.string(), details: z.string(), creatorName: z.string(), @@ -16,15 +16,15 @@ export const chicmozL2VerifiedContractAddressDataSchema = z.object({ repoUrl: z.string(), }); -export type ChicmozL2VerifiedContractAddressData = z.infer< - typeof chicmozL2VerifiedContractAddressDataSchema +export type ChicmozL2VerifiedContractInctanceData = z.infer< + typeof chicmozL2VerifiedContractInstanceDataSchema >; export const chicmozL2ContractInstanceDeluxeSchema = z.object({ ...chicmozL2ContractInstanceDeployedEventSchema.shape, ...chicmozL2ContractClassRegisteredEventSchema.shape, blockHeight: chicmozL2BlockSchema.shape.height.optional(), - verifiedInfo: chicmozL2VerifiedContractAddressDataSchema.optional(), + verifiedInfo: chicmozL2VerifiedContractInstanceDataSchema.optional(), }); export type ChicmozL2ContractInstanceDeluxe = z.infer< diff --git a/services/explorer-api/src/constants.ts b/services/explorer-api/src/constants.ts index 35cfd9a8..2ee7fc58 100644 --- a/services/explorer-api/src/constants.ts +++ b/services/explorer-api/src/constants.ts @@ -1,15 +1,15 @@ -import { ChicmozL2VerifiedContractAddressData } from "@chicmoz-pkg/types"; +import { ChicmozL2VerifiedContractInctanceData } from "@chicmoz-pkg/types"; export const CHAIN_NAME = "AZTEC"; export const SERVICE_NAME = "explorer-api"; -export const DEFAULT_VERIFIED_CONTRACT_ADDRESSES_DEV: ChicmozL2VerifiedContractAddressData[] = +export const DEFAULT_VERIFIED_CONTRACT_INSTANCES_DEV: ChicmozL2VerifiedContractInctanceData[] = [ { - contractInstanceAddress: + address: "0x0e5fe9a23c854f14262bb3b3e88dab8e33412d6db17baa199506f865ed746a0c", contractIdentifier: "Some contract name/id", - details: "This is a dummy verified contract", + details: "This is a dummy verified contract instance", creatorName: "Test", creatorContact: "email: test@test.com, discord: test#1234, telegram: @test", @@ -18,7 +18,7 @@ export const DEFAULT_VERIFIED_CONTRACT_ADDRESSES_DEV: ChicmozL2VerifiedContractA }, ]; -export const DEFAULT_VERIFIED_CONTRACT_ADDRESSES_PROD: ChicmozL2VerifiedContractAddressData[] = +export const DEFAULT_VERIFIED_CONTRACT_INSTANCES_PROD: ChicmozL2VerifiedContractInctanceData[] = [ - // TODO: Add verified contract addresses for production + // TODO: Add verified contract instances for production ]; diff --git a/services/explorer-api/src/database/controllers/l2contract/utils.ts b/services/explorer-api/src/database/controllers/l2contract/utils.ts index e2e65d3b..8d30858e 100644 --- a/services/explorer-api/src/database/controllers/l2contract/utils.ts +++ b/services/explorer-api/src/database/controllers/l2contract/utils.ts @@ -2,11 +2,11 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-unsafe-argument */ import { ChicmozL2ContractInstanceDeluxe, chicmozL2ContractInstanceDeluxeSchema } from "@chicmoz-pkg/types"; -import { VERIFIED_CONTRACT_ADDRESSES } from "../../../environment.js"; +import { VERIFIED_CONTRACT_INSTANCES } from "../../../environment.js"; // eslint-disable-next-line @typescript-eslint/no-explicit-any export const parseDeluxe = (contractClass: any, instance: any): ChicmozL2ContractInstanceDeluxe => { - const verifiedInfo = VERIFIED_CONTRACT_ADDRESSES.find(info => info.contractInstanceAddress === instance.address); + const verifiedInfo = VERIFIED_CONTRACT_INSTANCES.find(info => info.address === instance.address); return chicmozL2ContractInstanceDeluxeSchema.parse({ ...contractClass, verifiedInfo, diff --git a/services/explorer-api/src/environment.ts b/services/explorer-api/src/environment.ts index 7133308d..8f0efec9 100644 --- a/services/explorer-api/src/environment.ts +++ b/services/explorer-api/src/environment.ts @@ -1,16 +1,16 @@ export const NODE_ENV = process.env.NODE_ENV ?? "development"; import { CHAIN_NAME, - DEFAULT_VERIFIED_CONTRACT_ADDRESSES_DEV, - DEFAULT_VERIFIED_CONTRACT_ADDRESSES_PROD, + DEFAULT_VERIFIED_CONTRACT_INSTANCES_DEV, + DEFAULT_VERIFIED_CONTRACT_INSTANCES_PROD, } from "./constants.js"; const verifiedContractAddresses = NODE_ENV === "production" - ? DEFAULT_VERIFIED_CONTRACT_ADDRESSES_PROD - : DEFAULT_VERIFIED_CONTRACT_ADDRESSES_DEV; + ? DEFAULT_VERIFIED_CONTRACT_INSTANCES_PROD + : DEFAULT_VERIFIED_CONTRACT_INSTANCES_DEV; -export const VERIFIED_CONTRACT_ADDRESSES = verifiedContractAddresses +export const VERIFIED_CONTRACT_INSTANCES = verifiedContractAddresses export const PUBLIC_API_KEY = process.env.PUBLIC_API_KEY ?? "d1e2083a-660c-4314-a6f2-1d42f4b944f4"; diff --git a/services/explorer-api/src/http-server/routes/controllers/index.ts b/services/explorer-api/src/http-server/routes/controllers/index.ts index cd586746..a0692445 100644 --- a/services/explorer-api/src/http-server/routes/controllers/index.ts +++ b/services/explorer-api/src/http-server/routes/controllers/index.ts @@ -5,7 +5,7 @@ export * from "./txs.js"; export * from "./contract-classes.js"; export * from "./contract-class-functions.js"; export * from "./contract-instances.js"; -export * from "./verified-contracts.js"; +export * from "./verified-contract-instances.js"; export * from "./validators.js"; export * from "./search.js"; export * from "./stats.js"; diff --git a/services/explorer-api/src/http-server/routes/controllers/utils/open-api-responses.ts b/services/explorer-api/src/http-server/routes/controllers/utils/open-api-responses.ts index 92021175..5d326be7 100644 --- a/services/explorer-api/src/http-server/routes/controllers/utils/open-api-responses.ts +++ b/services/explorer-api/src/http-server/routes/controllers/utils/open-api-responses.ts @@ -8,7 +8,7 @@ import { chicmozL2TxEffectDeluxeSchema, chicmozL2UnconstrainedFunctionBroadcastedEventSchema, chicmozSearchResultsSchema, - chicmozL2VerifiedContractAddressDataSchema, + chicmozL2VerifiedContractInstanceDataSchema, } from "@chicmoz-pkg/types"; import { generateSchema } from "@anatine/zod-openapi"; @@ -46,7 +46,7 @@ export const contractClassUnconstrainedFunctionResponseArray = getResponse(z.arr export const contractInstanceResponse = getResponse(chicmozL2ContractInstanceDeluxeSchema); export const contractInstanceResponseArray = getResponse(z.array(chicmozL2ContractInstanceDeluxeSchema)); -export const verifiedContractResponse = getResponse(chicmozL2VerifiedContractAddressDataSchema); -export const verifiedContractResponseArray = getResponse(z.array(chicmozL2VerifiedContractAddressDataSchema)); +export const verifiedContractInstanceResponse = getResponse(chicmozL2VerifiedContractInstanceDataSchema); +export const verifiedContractInstanceResponseArray = getResponse(z.array(chicmozL2VerifiedContractInstanceDataSchema)); export const searchResultResponse = getResponse(chicmozSearchResultsSchema); diff --git a/services/explorer-api/src/http-server/routes/controllers/verified-contract-instances.ts b/services/explorer-api/src/http-server/routes/controllers/verified-contract-instances.ts new file mode 100644 index 00000000..a7298e84 --- /dev/null +++ b/services/explorer-api/src/http-server/routes/controllers/verified-contract-instances.ts @@ -0,0 +1,49 @@ +import { RequestHandler } from "express"; +import { VERIFIED_CONTRACT_INSTANCES } from "../../../environment.js"; +import { getVerifiedContractInstanceSchema } from "../paths_and_validation.js"; +import { + verifiedContractInstanceResponse, + verifiedContractInstanceResponseArray, +} from "./utils/open-api-responses.js"; + +export const openapi_GET_L2_VERIFIED_CONTRACT_INSTANCES = { + "/l2/verified-contract-instances": { + get: { + summary: "Get all verified contract instances", + responses: verifiedContractInstanceResponseArray, + }, + }, +}; + +export const GET_L2_VERIFIED_CONTRACT_INSTANCES: RequestHandler = (_req, res) => { + res.status(200).send(JSON.stringify(VERIFIED_CONTRACT_INSTANCES)); +}; + +export const openapi_GET_L2_VERIFIED_CONTRACT_INSTANCE = { + "/l2/verified-contract-instances/{contractInstanceAddress}": { + get: { + summary: "Get a verified contract instance by address", + parameters: [ + { + name: "contractInstanceAddress", + in: "path", + required: true, + schema: { + type: "string", + }, + }, + ], + responses: verifiedContractInstanceResponse, + }, + }, +}; + +export const GET_L2_VERIFIED_CONTRACT_INSTANCE: RequestHandler = (req, res) => { + const contractInstanceAddress = + getVerifiedContractInstanceSchema.parse(req).params.address; + const verifiedInfo = VERIFIED_CONTRACT_INSTANCES.find( + (info) => info.address === contractInstanceAddress + ); + if (!verifiedInfo) throw new Error("Verified contract instance not found"); // TODO: ensure this resolves in a 404 + res.status(200).send(JSON.stringify(verifiedInfo)); +}; diff --git a/services/explorer-api/src/http-server/routes/controllers/verified-contracts.ts b/services/explorer-api/src/http-server/routes/controllers/verified-contracts.ts deleted file mode 100644 index 02a9d279..00000000 --- a/services/explorer-api/src/http-server/routes/controllers/verified-contracts.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { RequestHandler } from "express"; -import { VERIFIED_CONTRACT_ADDRESSES } from "../../../environment.js"; -import { getVerifiedContractSchema } from "../paths_and_validation.js"; -import { - verifiedContractResponse, - verifiedContractResponseArray, -} from "./utils/open-api-responses.js"; - -export const openapi_GET_L2_VERIFIED_CONTRACTS = { - "/l2/verified-contracts": { - get: { - summary: "Get the latest block", - responses: verifiedContractResponseArray, - }, - }, -}; - -export const GET_L2_VERIFIED_CONTRACTS: RequestHandler = (_req, res) => { - res.status(200).send(JSON.stringify(VERIFIED_CONTRACT_ADDRESSES)); -}; - -export const openapi_GET_L2_VERIFIED_CONTRACT = { - "/l2/verified-contracts/{contractInstanceAddress}": { - get: { - summary: "Get a verified contract by address", - parameters: [ - { - name: "contractInstanceAddress", - in: "path", - required: true, - schema: { - type: "string", - }, - }, - ], - responses: verifiedContractResponse, - }, - }, -}; - -export const GET_L2_VERIFIED_CONTRACT: RequestHandler = (req, res) => { - const contractInstanceAddress = - getVerifiedContractSchema.parse(req).params.address; - const verifiedInfo = VERIFIED_CONTRACT_ADDRESSES.find( - (info) => info.contractInstanceAddress === contractInstanceAddress - ); - if (!verifiedInfo) throw new Error("Contract not found"); // TODO: ensure this resolves in a 404 - res.status(200).send(JSON.stringify(verifiedInfo)); -}; diff --git a/services/explorer-api/src/http-server/routes/index.ts b/services/explorer-api/src/http-server/routes/index.ts index 591cce24..22962b60 100644 --- a/services/explorer-api/src/http-server/routes/index.ts +++ b/services/explorer-api/src/http-server/routes/index.ts @@ -34,8 +34,8 @@ export const openApiPaths = { ...controller.openapi_GET_L2_CONTRACT_INSTANCE, ...controller.openapi_GET_L2_CONTRACT_INSTANCES, - ...controller.openapi_GET_L2_VERIFIED_CONTRACT, - ...controller.openapi_GET_L2_VERIFIED_CONTRACTS, + ...controller.openapi_GET_L2_VERIFIED_CONTRACT_INSTANCE, + ...controller.openapi_GET_L2_VERIFIED_CONTRACT_INSTANCES, ...controller.openapi_SEARCH, }; @@ -152,8 +152,8 @@ export const init = ({ router }: { router: Router }) => { router.get(paths.contractInstance, controller.GET_L2_CONTRACT_INSTANCE); router.get(paths.contractInstances, controller.GET_L2_CONTRACT_INSTANCES); - router.get(paths.verifiedContract, controller.GET_L2_VERIFIED_CONTRACT); - router.get(paths.verifiedContracts, controller.GET_L2_VERIFIED_CONTRACTS); + router.get(paths.verifiedContract, controller.GET_L2_VERIFIED_CONTRACT_INSTANCE); + router.get(paths.verifiedContracts, controller.GET_L2_VERIFIED_CONTRACT_INSTANCES); router.get(paths.validators, controller.GET_L2_VALIDATORS); diff --git a/services/explorer-api/src/http-server/routes/paths_and_validation.ts b/services/explorer-api/src/http-server/routes/paths_and_validation.ts index 11ef4c44..c9bbf465 100644 --- a/services/explorer-api/src/http-server/routes/paths_and_validation.ts +++ b/services/explorer-api/src/http-server/routes/paths_and_validation.ts @@ -39,8 +39,8 @@ export const paths = { search: "/l2/search", - verifiedContract: `/l2/verified-contracts/:${address}`, - verifiedContracts: "/l2/verified-contracts", + verifiedContract: `/l2/verified-contracts-instances/:${address}`, + verifiedContracts: "/l2/verified-contract-instances", validators: "/l2/validators", @@ -140,7 +140,7 @@ export const postContrctClassArtifactSchema = z.lazy(() => { export const getContractInstancesByContractClassIdSchema = getContractClassesByClassIdSchema; -export const getVerifiedContractSchema = getContractInstanceSchema; +export const getVerifiedContractInstanceSchema = getContractInstanceSchema; export const getSearchSchema = z.object({ query: chicmozSearchQuerySchema, diff --git a/services/explorer-ui/src/api/index.ts b/services/explorer-ui/src/api/index.ts index 84456ef1..4b7abb4c 100644 --- a/services/explorer-ui/src/api/index.ts +++ b/services/explorer-ui/src/api/index.ts @@ -1,5 +1,5 @@ export * from "./contract"; -export * from "./verified-contract"; +export * from "./verified-contract-instance"; export * from "./block"; export * from "./tx-effect"; export * from "./tx"; diff --git a/services/explorer-ui/src/api/verified-contract.ts b/services/explorer-ui/src/api/verified-contract-instance.ts similarity index 61% rename from services/explorer-ui/src/api/verified-contract.ts rename to services/explorer-ui/src/api/verified-contract-instance.ts index e4b6c3c2..f0d381e5 100644 --- a/services/explorer-ui/src/api/verified-contract.ts +++ b/services/explorer-ui/src/api/verified-contract-instance.ts @@ -1,28 +1,28 @@ import { - chicmozL2VerifiedContractAddressDataSchema, - type ChicmozL2VerifiedContractAddressData, + chicmozL2VerifiedContractInstanceDataSchema, + type ChicmozL2VerifiedContractInctanceData, } from "@chicmoz-pkg/types"; import { aztecExplorer } from "~/service/constants"; import client, { validateResponse } from "./client"; -export const VerifiedContractL2API = { +export const VerifiedContractInstanceL2API = { getVerifiedContract: async ( address: string - ): Promise => { + ): Promise => { const response = await client.get( aztecExplorer.getL2VerifiedContractByInstanceAddress(address) ); return validateResponse( - chicmozL2VerifiedContractAddressDataSchema, + chicmozL2VerifiedContractInstanceDataSchema, response.data ); }, getVerifiedContracts: async (): Promise< - ChicmozL2VerifiedContractAddressData[] + ChicmozL2VerifiedContractInctanceData[] > => { const response = await client.get(aztecExplorer.getL2VerifiedContracts); return validateResponse( - chicmozL2VerifiedContractAddressDataSchema.array(), + chicmozL2VerifiedContractInstanceDataSchema.array(), response.data ); }, diff --git a/services/explorer-ui/src/hooks/verified-contract-instance.ts b/services/explorer-ui/src/hooks/verified-contract-instance.ts new file mode 100644 index 00000000..f658e132 --- /dev/null +++ b/services/explorer-ui/src/hooks/verified-contract-instance.ts @@ -0,0 +1,14 @@ +import { type ChicmozL2VerifiedContractInctanceData } from "@chicmoz-pkg/types"; +import { type UseQueryResult, useQuery } from "@tanstack/react-query"; +import { VerifiedContractInstanceL2API } from "~/api"; +import { queryKeyGenerator } from "./utils"; + +export const useVerifiedContractInstances = (): UseQueryResult< + ChicmozL2VerifiedContractInctanceData[], + Error +> => { + return useQuery({ + queryKey: queryKeyGenerator.verifiedContracts, + queryFn: VerifiedContractInstanceL2API.getVerifiedContracts, + }); +}; diff --git a/services/explorer-ui/src/hooks/verified-contract.ts b/services/explorer-ui/src/hooks/verified-contract.ts deleted file mode 100644 index 128ac370..00000000 --- a/services/explorer-ui/src/hooks/verified-contract.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { type ChicmozL2VerifiedContractAddressData } from "@chicmoz-pkg/types"; -import { type UseQueryResult, useQuery } from "@tanstack/react-query"; -import { VerifiedContractL2API } from "~/api"; -import { queryKeyGenerator } from "./utils"; - -export const useVerifiedContracts = (): UseQueryResult< - ChicmozL2VerifiedContractAddressData[], - Error -> => { - return useQuery({ - queryKey: queryKeyGenerator.verifiedContracts, - queryFn: VerifiedContractL2API.getVerifiedContracts, - }); -}; diff --git a/services/explorer-ui/src/pages/contract-instance-details/index.tsx b/services/explorer-ui/src/pages/contract-instance-details/index.tsx index 4ea2cdaf..1f91b67c 100644 --- a/services/explorer-ui/src/pages/contract-instance-details/index.tsx +++ b/services/explorer-ui/src/pages/contract-instance-details/index.tsx @@ -4,7 +4,7 @@ import { useParams } from "@tanstack/react-router"; import { type FC } from "react"; import { KeyValueDisplay } from "~/components/info-display/key-value-display"; import { useContractInstance } from "~/hooks/"; -import { getContractData, getVerifiedContractData } from "./util"; +import { getContractData, getVerifiedContractInstanceData } from "./util"; import { routes } from "~/routes/__root"; import { CustomTooltip } from "~/components/custom-tooltip"; @@ -23,7 +23,7 @@ export const ContractInstanceDetails: FC = () => { if (error) return
Error
; if (!contractInstanceDetails) return
No data
; - const verfiedContractData = getVerifiedContractData(contractInstanceDetails); + const verfiedData = getVerifiedContractInstanceData(contractInstanceDetails); return (
@@ -42,14 +42,14 @@ export const ContractInstanceDetails: FC = () => {
- {verfiedContractData && ( + {verfiedData && (

- Verified contract data + Verified contract instance data
- - + + @@ -58,7 +58,7 @@ export const ContractInstanceDetails: FC = () => {
- +

diff --git a/services/explorer-ui/src/pages/contract-instance-details/util.ts b/services/explorer-ui/src/pages/contract-instance-details/util.ts index 2dc6f3f1..0687862f 100644 --- a/services/explorer-ui/src/pages/contract-instance-details/util.ts +++ b/services/explorer-ui/src/pages/contract-instance-details/util.ts @@ -40,13 +40,13 @@ export const getContractData = (data: ChicmozL2ContractInstanceDeluxe) => { label: "DEPLOYER CONTRACT 🤖", value: "This is a contract deployed by the hard-coded deployer. This message will only appear in development mode. But linking to verified contracts for good measure.", - link: routes.verifiedContracts.route, + link: routes.verifiedContractInstances.route, }); } return displayData; }; -export const getVerifiedContractData = (data: ChicmozL2ContractInstanceDeluxe) => { +export const getVerifiedContractInstanceData = (data: ChicmozL2ContractInstanceDeluxe) => { return data.verifiedInfo ? [ { diff --git a/services/explorer-ui/src/pages/verified-contracts.tsx b/services/explorer-ui/src/pages/verified-contract-instances.tsx similarity index 77% rename from services/explorer-ui/src/pages/verified-contracts.tsx rename to services/explorer-ui/src/pages/verified-contract-instances.tsx index 94177c20..c72e46b0 100644 --- a/services/explorer-ui/src/pages/verified-contracts.tsx +++ b/services/explorer-ui/src/pages/verified-contract-instances.tsx @@ -1,18 +1,18 @@ import { type FC } from "react"; import { Link } from "@tanstack/react-router"; -import { useVerifiedContracts } from "~/hooks/verified-contract"; +import { useVerifiedContractInstances } from "~/hooks/verified-contract-instance"; import { routes } from "~/routes/__root"; const contractInstanceDetailsRoute = routes.contracts.route + routes.contracts.children.instances.route + "/"; -export const VerifiedContracts: FC = () => { - const { data, isError, isLoading } = useVerifiedContracts(); +export const VerifiedContractInstances: FC = () => { + const { data, isError, isLoading } = useVerifiedContractInstances(); return (
-

Verified contracts

+

Verified contract instances

- Verified contracts mean that we have verified the deployer of the + Verified contract instances mean that we have verified the deployer of the contract.


@@ -22,14 +22,14 @@ export const VerifiedContracts: FC = () => {


- You can always find the latest verified contracts by checking{" "} + You can always find the latest verified contract instances by checking{" "} our github-repo - . If you think your contract should be verified, please create a PR to + . If you think your contract instance should be verified, please create a PR to that file.


@@ -37,7 +37,7 @@ export const VerifiedContracts: FC = () => {

Verified contracts:

{isLoading &&

Loading...

} {isError &&

Something went wrong...

} - {data && data.length === 0 &&

No verified contracts found

} + {data && data.length === 0 &&

No verified contract instances found

} {data && data.length > 0 && (
    {data.map((contract, index) => ( @@ -62,7 +62,7 @@ export const VerifiedContracts: FC = () => { diff --git a/services/explorer-ui/src/routeTree.gen.ts b/services/explorer-ui/src/routeTree.gen.ts index c66f307e..4766cacd 100644 --- a/services/explorer-ui/src/routeTree.gen.ts +++ b/services/explorer-ui/src/routeTree.gen.ts @@ -17,7 +17,9 @@ import { Route as TermsAndConditionsImport } from './routes/terms-and-conditions // Create Virtual Routes -const VerifiedContractsLazyImport = createFileRoute('/verified-contracts')() +const VerifiedContractInstancesLazyImport = createFileRoute( + '/verified-contract-instances', +)() const PrivacyPolicyLazyImport = createFileRoute('/privacy-policy')() const DevLazyImport = createFileRoute('/dev')() const AboutUsLazyImport = createFileRoute('/about-us')() @@ -36,12 +38,13 @@ const ContractsClassesIdVersionsVersionLazyImport = createFileRoute( // Create/Update Routes -const VerifiedContractsLazyRoute = VerifiedContractsLazyImport.update({ - path: '/verified-contracts', - getParentRoute: () => rootRoute, -} as any).lazy(() => - import('./routes/verified-contracts.lazy').then((d) => d.Route), -) +const VerifiedContractInstancesLazyRoute = + VerifiedContractInstancesLazyImport.update({ + path: '/verified-contract-instances', + getParentRoute: () => rootRoute, + } as any).lazy(() => + import('./routes/verified-contract-instances.lazy').then((d) => d.Route), + ) const PrivacyPolicyLazyRoute = PrivacyPolicyLazyImport.update({ path: '/privacy-policy', @@ -160,11 +163,11 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof PrivacyPolicyLazyImport parentRoute: typeof rootRoute } - '/verified-contracts': { - id: '/verified-contracts' - path: '/verified-contracts' - fullPath: '/verified-contracts' - preLoaderRoute: typeof VerifiedContractsLazyImport + '/verified-contract-instances': { + id: '/verified-contract-instances' + path: '/verified-contract-instances' + fullPath: '/verified-contract-instances' + preLoaderRoute: typeof VerifiedContractInstancesLazyImport parentRoute: typeof rootRoute } '/blocks/$blockNumber': { @@ -227,7 +230,7 @@ export const routeTree = rootRoute.addChildren({ AboutUsLazyRoute, DevLazyRoute, PrivacyPolicyLazyRoute, - VerifiedContractsLazyRoute, + VerifiedContractInstancesLazyRoute, BlocksBlockNumberLazyRoute, TxEffectsHashLazyRoute, BlocksIndexLazyRoute, @@ -250,7 +253,7 @@ export const routeTree = rootRoute.addChildren({ "/about-us", "/dev", "/privacy-policy", - "/verified-contracts", + "/verified-contract-instances", "/blocks/$blockNumber", "/tx-effects/$hash", "/blocks/", @@ -275,8 +278,8 @@ export const routeTree = rootRoute.addChildren({ "/privacy-policy": { "filePath": "privacy-policy.lazy.tsx" }, - "/verified-contracts": { - "filePath": "verified-contracts.lazy.tsx" + "/verified-contract-instances": { + "filePath": "verified-contract-instances.lazy.tsx" }, "/blocks/$blockNumber": { "filePath": "blocks/$blockNumber.lazy.tsx" diff --git a/services/explorer-ui/src/routes/__root.tsx b/services/explorer-ui/src/routes/__root.tsx index c962f8bf..df329c62 100644 --- a/services/explorer-ui/src/routes/__root.tsx +++ b/services/explorer-ui/src/routes/__root.tsx @@ -111,9 +111,9 @@ export const routes = { route: "/terms-and-conditions", title: "Terms and Conditions", }, - verifiedContracts: { - route: "/verified-contracts", - title: "Verified Contracts", + verifiedContractInstances: { + route: "/verified-contract-instances", + title: "Verified Contract Instances", }, }; diff --git a/services/explorer-ui/src/routes/verified-contract-instances.lazy.tsx b/services/explorer-ui/src/routes/verified-contract-instances.lazy.tsx new file mode 100644 index 00000000..538219c5 --- /dev/null +++ b/services/explorer-ui/src/routes/verified-contract-instances.lazy.tsx @@ -0,0 +1,6 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import { VerifiedContractInstances } from "~/pages/verified-contract-instances"; + +export const Route = createLazyFileRoute("/verified-contract-instances")({ + component: VerifiedContractInstances, +}); diff --git a/services/explorer-ui/src/routes/verified-contracts.lazy.tsx b/services/explorer-ui/src/routes/verified-contracts.lazy.tsx deleted file mode 100644 index edfcaf8b..00000000 --- a/services/explorer-ui/src/routes/verified-contracts.lazy.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import { createLazyFileRoute } from "@tanstack/react-router"; -import { VerifiedContracts } from "~/pages/verified-contracts"; - -export const Route = createLazyFileRoute("/verified-contracts")({ - component: VerifiedContracts, -}); From 6a4ba53e4b49a2b5d5d2299b1da4dfa129e6c82e Mon Sep 17 00:00:00 2001 From: filip Date: Wed, 8 Jan 2025 13:01:08 +0100 Subject: [PATCH 10/11] started --- README.md | 2 +- k6/stress-test.js | 2 +- k8s/production/skaffold.production.full.yaml | 4 ++-- k8s/production/skaffold.production.light.yaml | 4 ++-- .../src/http-server/open-api-spec.ts | 2 +- services/explorer-ui/index.html | 20 +++++++++---------- .../src/components/ui/chicmoz-home-link.tsx | 2 +- .../explorer-ui/src/pages/privacy-policy.tsx | 2 +- 8 files changed, 19 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index fb3ce8e5..762f8207 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Chicmoz - [aztecscout.xyz](https://aztecscout.xyz) +# Chicmoz - [aztecscan.xyz](https://aztecscan.xyz) ## running locally diff --git a/k6/stress-test.js b/k6/stress-test.js index 9130233f..93c1dd67 100644 --- a/k6/stress-test.js +++ b/k6/stress-test.js @@ -44,7 +44,7 @@ export const options = { }, }; -const BASE_URL = "https://api.aztecscout.xyz/v1/d1e2083a-660c-4314-a6f2-1d42f4b944f4"; +const BASE_URL = "https://api.aztecscan.xyz/v1/d1e2083a-660c-4314-a6f2-1d42f4b944f4"; let VALID_BLOCK_HEIGHT = 2; diff --git a/k8s/production/skaffold.production.full.yaml b/k8s/production/skaffold.production.full.yaml index 172e70cb..9f4ca96f 100644 --- a/k8s/production/skaffold.production.full.yaml +++ b/k8s/production/skaffold.production.full.yaml @@ -14,8 +14,8 @@ build: dockerfile: Dockerfile buildArgs: NODE_ENV: "production" - VITE_API_URL: "https://api.aztecscout.xyz/v1/d1e2083a-660c-4314-a6f2-1d42f4b944f4" # TODO: change the api key - VITE_WS_URL: "wss://ws.aztecscout.xyz" + VITE_API_URL: "https://api.aztecscan.xyz/v1/d1e2083a-660c-4314-a6f2-1d42f4b944f4" # TODO: change the api key + VITE_WS_URL: "wss://ws.aztecscan.xyz" VITE_DISCORD_URL: "https://discord.gg/obscura-network" VITE_X_URL: "https://x.com/Obscura_Network" VITE_GITHUB_URL: "https://github.com/aztlan-labs/chicmoz" diff --git a/k8s/production/skaffold.production.light.yaml b/k8s/production/skaffold.production.light.yaml index e39f2024..d590e7ae 100644 --- a/k8s/production/skaffold.production.light.yaml +++ b/k8s/production/skaffold.production.light.yaml @@ -14,8 +14,8 @@ build: dockerfile: Dockerfile buildArgs: NODE_ENV: "production" - VITE_API_URL: "https://api.aztecscout.xyz/v1/d1e2083a-660c-4314-a6f2-1d42f4b944f4" # TODO: change the api key - VITE_WS_URL: "wss://ws.aztecscout.xyz" + VITE_API_URL: "https://api.aztecscan.xyz/v1/d1e2083a-660c-4314-a6f2-1d42f4b944f4" # TODO: change the api key + VITE_WS_URL: "wss://ws.aztecscan.xyz" VITE_DISCORD_URL: "https://discord.gg/obscura-network" VITE_X_URL: "https://x.com/Obscura_Network" VITE_GITHUB_URL: "https://github.com/aztlan-labs/chicmoz" diff --git a/services/explorer-api/src/http-server/open-api-spec.ts b/services/explorer-api/src/http-server/open-api-spec.ts index 86c6b2b3..cfeff6e0 100644 --- a/services/explorer-api/src/http-server/open-api-spec.ts +++ b/services/explorer-api/src/http-server/open-api-spec.ts @@ -11,7 +11,7 @@ export const genereateOpenApiSpec = () => ({ }, servers: [ { - url: "https://api.aztecscout.xyz/v1/{apiKey}", + url: "https://api.aztecscan.xyz/v1/{apiKey}", variables: { apiKey: { default: PUBLIC_API_KEY, diff --git a/services/explorer-ui/index.html b/services/explorer-ui/index.html index 00b91d8e..7ecadaeb 100644 --- a/services/explorer-ui/index.html +++ b/services/explorer-ui/index.html @@ -3,34 +3,34 @@ - + - + - - + + - + - - + + - Aztec-Scout + Aztec-Scan
    diff --git a/services/explorer-ui/src/components/ui/chicmoz-home-link.tsx b/services/explorer-ui/src/components/ui/chicmoz-home-link.tsx index 6009d357..047c09ae 100644 --- a/services/explorer-ui/src/components/ui/chicmoz-home-link.tsx +++ b/services/explorer-ui/src/components/ui/chicmoz-home-link.tsx @@ -14,7 +14,7 @@ export function ChicmozHomeLink({

    - Aztec-Scout + Aztec-Scan

diff --git a/services/explorer-ui/src/pages/privacy-policy.tsx b/services/explorer-ui/src/pages/privacy-policy.tsx index 666e8398..74aeb554 100644 --- a/services/explorer-ui/src/pages/privacy-policy.tsx +++ b/services/explorer-ui/src/pages/privacy-policy.tsx @@ -16,7 +16,7 @@ export const PrivacyPolicy: FC = () => {

  • - Visit our website at https://aztecscout.xyz, or any website of ours + Visit our website at https://aztecscan.xyz, or any website of ours that links to this privacy notice{" "}
  • From ffecc21f06106b47b6b53651623eb5c6de6334d9 Mon Sep 17 00:00:00 2001 From: filip Date: Sat, 11 Jan 2025 12:42:38 +0100 Subject: [PATCH 11/11] lol --- .../migrations/0000_youthful_colossus.sql | 410 ------------------ 1 file changed, 410 deletions(-) delete mode 100644 services/explorer-api/migrations/0000_youthful_colossus.sql diff --git a/services/explorer-api/migrations/0000_youthful_colossus.sql b/services/explorer-api/migrations/0000_youthful_colossus.sql deleted file mode 100644 index d6241cb6..00000000 --- a/services/explorer-api/migrations/0000_youthful_colossus.sql +++ /dev/null @@ -1,410 +0,0 @@ -CREATE TABLE IF NOT EXISTS "aztec-chain-connection" ( - "hash" varchar PRIMARY KEY NOT NULL, - "created_at" timestamp DEFAULT now() NOT NULL, - "updated_at" timestamp DEFAULT now() NOT NULL, - "chain_height" integer NOT NULL, - "latest_processed_height" integer NOT NULL, - "counter" integer DEFAULT 0 NOT NULL, - "rpc_url" varchar NOT NULL, - "node_version" varchar NOT NULL, - "l1_chain_id" integer NOT NULL, - "protocol_version" integer NOT NULL, - "enr" varchar, - "l1_contract_addresses" jsonb NOT NULL, - "protocol_contract_addresses" jsonb NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "archive" ( - "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, - "root" varchar(66), - "next_available_leaf_index" integer NOT NULL, - "block_hash" varchar NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "l2Block" ( - "hash" varchar PRIMARY KEY NOT NULL, - "height" bigint NOT NULL, - CONSTRAINT "l2Block_height_unique" UNIQUE("height") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "body" ( - "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, - "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, - "index" integer NOT NULL, - "leaf_slot" varchar(66) NOT NULL, - "value" varchar(66) NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "tx_effect" ( - "tx_hash" varchar PRIMARY KEY NOT NULL, - "body_id" uuid NOT NULL, - "tx_time_of_birth" timestamp DEFAULT now() NOT NULL, - "index" integer NOT NULL, - "revert_code" smallint NOT NULL, - "transaction_fee" bigint NOT NULL, - "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 -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "content_commitment" ( - "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, - "header_id" uuid NOT NULL, - "num_txs" bigint NOT NULL, - "blobs_hash" "bytea" NOT NULL, - "in_hash" "bytea" NOT NULL, - "out_hash" "bytea" NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "gas_fees" ( - "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, - "global_variables_id" uuid NOT NULL, - "fee_per_da_gas" bigint, - "fee_per_l2_gas" bigint -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "global_variables" ( - "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, - "header_id" uuid NOT NULL, - "chain_id" bigint NOT NULL, - "version" bigint NOT NULL, - "block_number" bigint NOT NULL, - "slot_number" bigint NOT NULL, - "timestamp" bigint NOT NULL, - "coinbase" varchar(42) NOT NULL, - "fee_recipient" varchar(66) NOT NULL -); ---> statement-breakpoint -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 -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "l1_to_l2_message_tree" ( - "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, - "root" varchar(66), - "next_available_leaf_index" integer NOT NULL, - "state_id" uuid NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "last_archive" ( - "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, - "root" varchar(66), - "next_available_leaf_index" integer NOT NULL, - "header_id" uuid NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "note_hash_tree" ( - "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, - "root" varchar(66), - "next_available_leaf_index" integer NOT NULL, - "state_partial_id" uuid NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "nullifier_tree" ( - "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, - "root" varchar(66), - "next_available_leaf_index" integer NOT NULL, - "state_partial_id" uuid NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "partial" ( - "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, - "state_id" uuid NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "public_data_tree" ( - "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, - "root" varchar(66), - "next_available_leaf_index" integer NOT NULL, - "state_partial_id" uuid NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "state" ( - "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, - "header_id" uuid NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "tx" ( - "hash" varchar PRIMARY KEY NOT NULL, - "birth_timestamp" timestamp DEFAULT now() NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "l2_contract_class_registered" ( - "block_hash" varchar NOT NULL, - "contract_class_id" varchar(66) NOT NULL, - "version" bigint NOT NULL, - "artifact_hash" varchar(66) NOT NULL, - "private_functions_root" varchar(66) NOT NULL, - "packed_bytecode" "bytea" NOT NULL, - "artifact_json" varchar, - CONSTRAINT "contract_class_id_version" PRIMARY KEY("contract_class_id","version") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "l2_contract_instance_deployed" ( - "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, - "block_hash" varchar NOT NULL, - "address" varchar(66) NOT NULL, - "version" integer NOT NULL, - "salt" varchar(66) NOT NULL, - "contract_class_id" varchar(66) NOT NULL, - "initialization_hash" varchar(66) NOT NULL, - "deployer" varchar(66) NOT NULL, - "public_keys_master_nullifier_public_key_x" varchar(66) NOT NULL, - "public_keys_master_nullifier_public_key_y" varchar(66) NOT NULL, - "public_keys_master_nullifier_public_key_is_infinite" boolean NOT NULL, - "public_keys_master_nullifier_public_key_kind" varchar NOT NULL, - "public_keys_master_incoming_viewing_public_key_x" varchar(66) NOT NULL, - "public_keys_master_incoming_viewing_public_key_y" varchar(66) NOT NULL, - "public_keys_master_incoming_viewing_public_key_is_infinite" boolean NOT NULL, - "public_keys_master_incoming_viewing_public_key_kind" varchar NOT NULL, - "public_keys_master_outgoing_viewing_public_key_x" varchar(66) NOT NULL, - "public_keys_master_outgoing_viewing_public_key_y" varchar(66) NOT NULL, - "public_keys_master_outgoing_viewing_public_key_is_infinite" boolean NOT NULL, - "public_keys_master_outgoing_viewing_public_key_kind" varchar NOT NULL, - "public_keys_master_tagging_public_key_x" varchar(66) NOT NULL, - "public_keys_master_tagging_public_key_y" varchar(66) NOT NULL, - "public_keys_master_tagging_public_key_is_infinite" boolean NOT NULL, - "public_keys_master_tagging_public_key_kind" varchar NOT NULL, - CONSTRAINT "l2_contract_instance_deployed_contract_class_id_address_version_unique" UNIQUE("contract_class_id","address","version") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "l2_private_function" ( - "contract_class_id" varchar(66) NOT NULL, - "artifact_metadata_hash" varchar(66) NOT NULL, - "unconstrained_functions_artifact_tree_root" varchar(66) NOT NULL, - "private_function_tree_sibling_path" jsonb NOT NULL, - "private_function_tree_leaf_index" bigint NOT NULL, - "artifact_function_tree_sibling_path" jsonb NOT NULL, - "artifact_function_tree_leaf_index" bigint NOT NULL, - "private_function_selector_value" bigint NOT NULL, - "private_function_metadata_hash" varchar(66) NOT NULL, - "private_function_vk_hash" varchar(66) NOT NULL, - "private_function_bytecode" "bytea" NOT NULL, - CONSTRAINT "private_function_contract_class" PRIMARY KEY("contract_class_id","private_function_selector_value") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "l2_unconstrained_function" ( - "contract_class_id" varchar(66) NOT NULL, - "artifact_metadata_hash" varchar(66) NOT NULL, - "private_functions_artifact_tree_root" varchar(66) NOT NULL, - "artifact_function_tree_sibling_path" jsonb NOT NULL, - "artifact_function_tree_leaf_index" bigint NOT NULL, - "unconstrained_function_selector_value" bigint NOT NULL, - "unconstrained_function_metadata_hash" varchar(66) NOT NULL, - "unconstrained_function_bytecode" "bytea" NOT NULL, - CONSTRAINT "unconstrained_function_contract_class" PRIMARY KEY("contract_class_id","unconstrained_function_selector_value") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "l1_l2_validator_proposer" ( - "attester_address" varchar(42) NOT NULL, - "proposer" varchar(42) NOT NULL, - "timestamp" timestamp DEFAULT now() NOT NULL, - CONSTRAINT "l1_l2_validator_proposer_attester_address_timestamp_pk" PRIMARY KEY("attester_address","timestamp") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "l1_l2_validator_stake" ( - "attester_address" varchar(42) NOT NULL, - "stake" numeric(77, 0) NOT NULL, - "timestamp" timestamp DEFAULT now() NOT NULL, - CONSTRAINT "l1_l2_validator_stake_attester_address_timestamp_pk" PRIMARY KEY("attester_address","timestamp") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "l1_l2_validator_status" ( - "attester_address" varchar(42) NOT NULL, - "status" smallint NOT NULL, - "timestamp" timestamp DEFAULT now() NOT NULL, - CONSTRAINT "l1_l2_validator_status_attester_address_timestamp_pk" PRIMARY KEY("attester_address","timestamp") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "l1_l2_validator" ( - "attester" varchar(42) PRIMARY KEY NOT NULL, - "first_seen_at" timestamp NOT NULL -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "l1_l2_validator_withdrawer" ( - "attester_address" varchar(42) NOT NULL, - "withdrawer" varchar(42) NOT NULL, - "timestamp" timestamp DEFAULT now() NOT NULL, - CONSTRAINT "l1_l2_validator_withdrawer_attester_address_timestamp_pk" PRIMARY KEY("attester_address","timestamp") -); ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "archive" ADD CONSTRAINT "archive_block_hash_l2Block_hash_fk" FOREIGN KEY ("block_hash") REFERENCES "public"."l2Block"("hash") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "body" ADD CONSTRAINT "body_block_hash_l2Block_hash_fk" FOREIGN KEY ("block_hash") REFERENCES "public"."l2Block"("hash") ON DELETE cascade ON UPDATE no action; -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 - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "tx_effect" ADD CONSTRAINT "tx_effect_body_id_body_id_fk" FOREIGN KEY ("body_id") REFERENCES "public"."body"("id") ON DELETE cascade ON UPDATE no action; -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 - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "gas_fees" ADD CONSTRAINT "gas_fees_global_variables_id_global_variables_id_fk" FOREIGN KEY ("global_variables_id") REFERENCES "public"."global_variables"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "global_variables" ADD CONSTRAINT "global_variables_header_id_header_id_fk" FOREIGN KEY ("header_id") REFERENCES "public"."header"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "header" ADD CONSTRAINT "header_block_hash_l2Block_hash_fk" FOREIGN KEY ("block_hash") REFERENCES "public"."l2Block"("hash") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "l1_to_l2_message_tree" ADD CONSTRAINT "l1_to_l2_message_tree_state_id_state_id_fk" FOREIGN KEY ("state_id") REFERENCES "public"."state"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "last_archive" ADD CONSTRAINT "last_archive_header_id_header_id_fk" FOREIGN KEY ("header_id") REFERENCES "public"."header"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "note_hash_tree" ADD CONSTRAINT "note_hash_tree_state_partial_id_partial_id_fk" FOREIGN KEY ("state_partial_id") REFERENCES "public"."partial"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "nullifier_tree" ADD CONSTRAINT "nullifier_tree_state_partial_id_partial_id_fk" FOREIGN KEY ("state_partial_id") REFERENCES "public"."partial"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "partial" ADD CONSTRAINT "partial_state_id_state_id_fk" FOREIGN KEY ("state_id") REFERENCES "public"."state"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "public_data_tree" ADD CONSTRAINT "public_data_tree_state_partial_id_partial_id_fk" FOREIGN KEY ("state_partial_id") REFERENCES "public"."partial"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "state" ADD CONSTRAINT "state_header_id_header_id_fk" FOREIGN KEY ("header_id") REFERENCES "public"."header"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "l2_contract_class_registered" ADD CONSTRAINT "l2_contract_class_registered_block_hash_l2Block_hash_fk" FOREIGN KEY ("block_hash") REFERENCES "public"."l2Block"("hash") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "l2_contract_instance_deployed" ADD CONSTRAINT "l2_contract_instance_deployed_block_hash_l2Block_hash_fk" FOREIGN KEY ("block_hash") REFERENCES "public"."l2Block"("hash") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "l2_contract_instance_deployed" ADD CONSTRAINT "contract_class" FOREIGN KEY ("contract_class_id","version") REFERENCES "public"."l2_contract_class_registered"("contract_class_id","version") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "l1_l2_validator_proposer" ADD CONSTRAINT "l1_l2_validator_proposer_attester_address_l1_l2_validator_attester_fk" FOREIGN KEY ("attester_address") REFERENCES "public"."l1_l2_validator"("attester") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "l1_l2_validator_stake" ADD CONSTRAINT "l1_l2_validator_stake_attester_address_l1_l2_validator_attester_fk" FOREIGN KEY ("attester_address") REFERENCES "public"."l1_l2_validator"("attester") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "l1_l2_validator_status" ADD CONSTRAINT "l1_l2_validator_status_attester_address_l1_l2_validator_attester_fk" FOREIGN KEY ("attester_address") REFERENCES "public"."l1_l2_validator"("attester") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "l1_l2_validator_withdrawer" ADD CONSTRAINT "l1_l2_validator_withdrawer_attester_address_l1_l2_validator_attester_fk" FOREIGN KEY ("attester_address") REFERENCES "public"."l1_l2_validator"("attester") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -CREATE INDEX IF NOT EXISTS "tx_hash_index" ON "tx_effect" USING btree ("tx_hash"); \ No newline at end of file